使用集合来排序ArrayList <hashmap <string,string>&gt;比较一段字符串</hashmap <string,string>

时间:2014-06-13 08:34:09

标签: java string arraylist

我需要排序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用户)。 感谢

4 个答案:

答案 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);
    }
}

此外,该课程显然还应提供hashCodeequals的实施方案。由你决定...

使用这种方法,您不再需要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
}

注意:

  1. 您只需要编译一次模式(第一行);然后它可以重复使用。例如,将其放入静态或非静态成员变量中。
  2. \\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的所有功能都可供您使用,您也可以实现自己的排序逻辑。