我需要排序HashMap的ArrayList,这是我的代码:
ArrayList<HashMap<String,String>> fiduList = new ArrayList<HashMap<String,String>>();
for (MapPoint aList: MapPointsList) {
HashMap<String, String> fidu = new HashMap<String, String>();
fidu.put(KEY_NAME, aList.getRealname());
fidu.put(KEY_TYPE, aList.getType());
fiduList.add(fidu);
}
getRealname获取如下字符串:AABB / CCCC / DDDD。例如:
AA11/4352/G435;
AA23/0234/J543;
AA02/0032/K123;
我需要排序ArrayList,比较第一个DDDD,CCCC和BB。
使用我的代码,我只能对所有字符串进行排序:
Collections.sort(fiduList, new Comparator<HashMap<String,String>>(){
public int compare(HashMap<String,String> mapping1,HashMap<String,String> mapping2){
return mapping1.get(KEY_NAME).compareTo(mapping2.get(KEY_NAME));
}
});
我该如何解决这个问题? (我是新的Java用户)。 感谢
答案 0 :(得分:2)
我会建议另一种方法。您似乎使用地图来保存对象的两个属性 - 名称和类型。如果是这样,地图就不是合适的数据结构。
你真的应该为它创建一个自己的类:
public final class Fidu {
private final String name;
private final String type;
public Fidu(String name, String type) {
this.name = name;
this.type = type;
}
}
当继续分析需求时,似乎名称由三部分组成,必须从分隔的字符串中解析。因此,您的类应该反映出来(注意私有构造函数和工厂方法):
public final class Fidu {
private final String namePart1;
private final String namePart2;
private final String namePart3;
private final String type;
private Fidu(String namePart1, String namePart2, String namePart3, String type) {
this.namePart1 = namePart1;
this.namePart2 = namePart2;
this.namePart3 = namePart3;
this.type = type;
}
public static Fidu parse(String name, String type) {
String[] parts = name.split("/");
if (parts.length != 3)
throw new IllegalArgumentException(name);
return new Fidu(parts[0], parts[1], parts[2], type);
}
}
最后,你应该在Fidu
类型的对象上考虑自然排序:
public final class Fidu implements Comparable<Fidu> {
...
public int compareTo(Fidu other) {
// an example:
int compare = this.namePart3.compareTo(other.namePart3);
if (compare != 0)
return compare;
compare = this.namePart2.compareTo(other.namePart2);
if (compare != 0)
return compare;
return this.namePart1.compareTo(other.namePart1);
}
}
此外,该课程显然还应提供hashCode
和equals
的实施方案。由你决定...
使用这种方法,您不再需要ArrayList<HashMap<String, String>>
,而只需使用List<Fidu>
(顺便说一句,对于变量的类型,始终使用接口而不是实现)。然后可以使用
List<Fidu> fiduList = ...
Collections.sort(fiduList);
答案 1 :(得分:0)
在Comparator#compare
方法中,您可以使用班级java.util.regex.Pattern
使用正则表达式拆分真实姓名:
Pattern pattern = Pattern.compile("(\\w{2})(\\w{2})/(\\w{4})/(\\w{4})");
Matcher matcher = pattern.matcher(realName);
if (matcher.matches()) {
String aa = matcher.group(1);
String bb = matcher.group(2);
String cccc = matcher.group(3);
String dddd = matcher.group(4);
// TODO: compare
} else {
// TODO: real name does not match pattern
}
注意:
\\w
匹配以下字符:'a'-'z', 'A'-'Z', '0'-'9', '_'
。如果这还不够,请使用其他charachter类或直接指定自定义字符类,如[A-Z0-9]
答案 2 :(得分:0)
更改您的排序:
return mapping1.get(KEY_NAME).compareTo(mapping2.get(KEY_NAME));
对此:
String[] leftStrings = mapping1.get(KEY_NAME).split("/");
String[] rightStrings = mapping2.get(KEY_NAME).split("/");
int comp = 0;
for (int i = leftStrings.length - 1; i >=0; i--) {
comp = leftStrings[i].compareTo(rightStrings[i]);
if (comp != 0) {
break;
}
}
return comp;
这会将您的字符串分成三部分,然后按字母顺序对字符串进行排序。我们第一次看到不匹配时,会报告排序顺序。
答案 3 :(得分:-2)
Extend TreeMap创建自己的map类,在这个类中提供了对Map对象进行排序的方法,对于字符串比较,可以将Comparator与自定义逻辑一起传递给TreeMap类。
http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html
这样一来,Map的所有功能都可供您使用,您也可以实现自己的排序逻辑。