Java me j2me-按两个或多个条件筛选结果

Java me j2me-按两个或多个条件筛选结果,java-me,Java Me,我正在尝试使用界面过滤一些记录。在我的应用程序中,我有两个类似于此的界面,用户可以在上面输入ID或名称(他/她可以同时输入,也可以不输入) 以下是我迄今为止所做的工作: 客户过滤器 在这里,如果用户没有输入ID,我会将0作为默认值传递,这就是我评估customerID的原因=0 public class CustomerFilter implements RecordFilter { private String mName_Filter; private int mID_F

我正在尝试使用界面过滤一些记录。在我的应用程序中,我有两个类似于此的界面,用户可以在上面输入ID或名称(他/她可以同时输入,也可以不输入)

以下是我迄今为止所做的工作:

客户过滤器

在这里,如果用户没有输入ID,我会将0作为默认值传递,这就是我评估
customerID的原因=0

public class CustomerFilter implements RecordFilter {

    private String mName_Filter;
    private int mID_Filter;

    public CustomerFilter(String name_Filter, int id_Filter) {
        this.mName_Filter = name_Filter.toLowerCase();
        this.mID_Filter = id_Filter;
    }

    public boolean matches(byte[] candidate) {
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(candidate);
            DataInputStream dis = new DataInputStream(bis);
            int customerID = dis.readInt();
            String customerName = dis.readUTF().toLowerCase();
            if ((customerName != null && customerName.indexOf(mName_Filter) != -1) && (customerID != 0 && customerID == mID_Filter))                
                return true;
            if (customerName != null && customerName.indexOf(mName_Filter) != -1 && customerID == 0) 
                return true;
            if (customerName == null && (customerID != 0 && customerID == mID_Filter)) 
                return true;
            if (customerName == null && customerID == 0) 
                return true;

        } catch (IOException ex) {
            //What's the point in catching a exception here???
        }
        return false;
    }
}
搜索方法:

注意:此方法位于我称之为“RMSCustomer”的类中,在该类中,我处理与RMS访问相关的所有内容。搜索方法接收两个参数(id和name),并使用它们来实例化过滤器

  public Customer[] search(int id, String name) throws RecordStoreException, IOException {
        RecordStore rs = null;
        RecordEnumeration recEnum = null;
        Customer[] customerList = null;
        try {
            rs = RecordStore.openRecordStore(mRecordStoreName, true);           
            if (rs.getNumRecords() > 0) {
                CustomerFilter filter = new CustomerFilter(name, id);            
                try {
                    recEnum = rs.enumerateRecords(filter, null, false);
                    if (recEnum.numRecords() > 0) {                  
                        customerList = new Customer[recEnum.numRecords()];
                        int counter = 0;
                        while (recEnum.hasNextElement()) {
                            Customer cust;
                            int idRecord = recEnum.nextRecordId();
                            byte[] filterRecord = rs.getRecord(idRecord);                      
                            cust = parseRecord(filterRecord);
                            cust.idRecord = idRecord;
                            customerList[counter] = cust;
                            counter++;
                        }
                    } 
                    else{
                        customerList = new Customer[0];
                        //How to send a message to the midlet from here
                        //saying something like "No Record Exists.Please select another filter"
                    }                   
                } finally {
                    recEnum.destroy();
                }
            }
            else{
                //How to send a message to the midlet from here
                //saying something like "No Record Exists.Please Add record"
            }
        } finally {
            rs.closeRecordStore();
        }
        return customerList;
    }
尽管上述代码有效,但我仍有一些问题:

过滤器中

1) 如何改进用于计算过滤器可能值(名称、id)的代码?如果我有更多的过滤器呢??我需要测试所有可能的组合吗

2) 如果用户既不输入ID也不输入名称,我应该显示所有记录还是显示消息“请输入名称或ID”??在这种情况下你会怎么做

3) 当我在过滤器里什么都做不了的时候,为什么我必须在过滤器里放一个试捕器??我不能从那里显示任何警报,可以吗

搜索方法中:

1) 如何从该方法向用户显示正确的消息?类似于“无记录”(请参阅代码中的“其他”部分)

抱歉,如果我问了太多的问题,那只是有一些完整的过滤器示例

提前谢谢

如何改进用于计算 过滤器(名称、id)

ID是记录中的第一个字段,也是搜索速度最快的字段。如果ID匹配,则客户名称实际上并不重要。通常,您将查找ID匹配或客户名称匹配的记录,因此一旦ID匹配,您可以返回true。这是我对
CustomerFilter
类的建议:

public class CustomerFilter implements RecordFilter {

    private String mName_Filter;

    //Use Integer instead of int. 
    //This way we can use null instead of zero if the user didn't type an ID.
    //This allows us to store IDs with values like 0, -1, etc.
    //It is a bit less memory efficient,
    //but you are not creating hundreds of filters, are you? (If you are, don't).
    private Integer mID_Filter; 

    public CustomerFilter(String name_Filter, Integer id_Filter) {
        this.mName_Filter = normalizeString(mName_Filter);
        this.mID_Filter = id_Filter;
    }

    //You should move this function to an StringUtils class and make it public.
    //Other filters might need it in the future.
    private static String normalizeString(final String s){
        if(s != null){      
            //Warning: you might want to replace accentuated chars as well.
            return s.toLowerCase();
        }
        return null;
    }

    public boolean matches(byte[] candidate) {
        ByteArrayInputStream bis = new ByteArrayInputStream(candidate);
        DataInputStream dis = new DataInputStream(bis); 

        try {               
            if(mID_Filter != null){
                //If the ID is unique, and the search is ID OR other fields, this is fine
                int customerID = dis.readInt();

                if(mID_Filter.intValue == customerID){
                    return true;
                } else {
                    return false; 
                }
            }

            if(mName_Filter != null){
                String customerName = normalizeString(dis.readUTF());
                if(customerName != null && customerName.indexOf(mName_Filter) != -1){
                    return true;
                }
            }

            if(mID_Filter == null && mName_Filter == null){
                return true; // No filtering, every record matches.
            }
        } catch (IOException ex) {
            //Never swallow exceptions.
            //Even if you are using an underlying ByteArrayInputStream, an exception 
            //can still be thrown when reading from DataInputStream if you try to read
            //fields that do not exists.

            //But even if no exceptions were ever thrown, never swallow exceptions :)
            System.err.println(ex);

            //Optional: throw ex;
        } finally {
            //Always close streams.
            if(bis != null){
                try {
                    bis.close();
                } catch(IOException ioe){
                    System.err.println(ioe);
                }
            }

            if(dis != null){
                try {
                    dis.close();
                } catch(IOException ioe){
                    System.err.println(ioe);
                }
            }
        }

        return false;
    }
}



如果我有更多的过滤器怎么办?我会测试所有可能的过滤器吗 组合

这取决于您的项目。通常ID是唯一的,并且不存在具有相同ID的两条记录。在这种情况下,您应该明确设计屏幕,以便用户了解他键入的ID或他填写的其他字段。条件如下:

idMatches OR (field1Matches AND field2Matches AND ... fieldNMatches)
如果用户未键入任何内容,则将返回所有记录

但这又是一个用户体验问题,我不知道它是否符合您的要求

从编程的角度来看,很明显,您添加的字段越多,过滤器就会变得越混乱。为了防止这种情况,您可以使用,甚至,这样的模式。不过,您可能必须以良好的设计换取性能




如果用户既不输入ID也不输入名称,我应该显示吗 所有记录或我应该显示一条消息“请输入姓名或 身份证?,在这种情况下你会怎么做

视情况而定。是否有其他方式查看所有记录?如果有,则显示消息




当我做不到的时候,为什么我必须在过滤器里放一个试捕器 有什么吗?我不能从那里显示任何警报,或者我可以吗

您不应该这样做。此类只负责筛选,不负责与用户交互。您仍然可以从catch子句中记录错误,然后再次抛出异常。这将将异常传播到
RMSCustomer.search
,因此无论客户端代码调用什么函数,该函数都将以相同的方式处理异常您正在处理该方法抛出的其他流。但保留finally子句以关闭流




如何从该方法向用户显示正确的消息? 类似于“无记录”(请参阅代码中的“其他”部分)

您不应该从RMSCustomer类中执行任何与GUI相关的操作(如显示对话框)。即使您没有使用模型-视图-控制器模式,您仍然希望让您的类专注于单个职责(管理记录)。这称为。 保持类与GUI隔离将允许您在没有GUI的环境中测试和重用它。
当结果为零时,屏幕应处理无记录的情况。此处可以使用lenght==0的数组,屏幕将显示“无结果”消息。对于其他类型的错误,您可以从
RMSCustomer.search
方法扩展Exception类并抛出您自己的自定义异常,即:
RecordParsingException
。screen类随后将以用户语言将不同的异常映射到错误消息。

非常感谢Smith先生