Java me j2me-按两个或多个条件筛选结果
我正在尝试使用界面过滤一些记录。在我的应用程序中,我有两个类似于此的界面,用户可以在上面输入ID或名称(他/她可以同时输入,也可以不输入) 以下是我迄今为止所做的工作: 客户过滤器 在这里,如果用户没有输入ID,我会将0作为默认值传递,这就是我评估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
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先生