如何在HashMap中获得排序后的arrayList?

时间:2019-08-29 08:32:07

标签: java arraylist hashmap

我尝试了以下Java代码。但是我无法获得正确的输出。

public static void main(String[] args) throws IOException 

    {
ArrayList<HashMap<ArrayList<String>,Integer>> result=new ArrayList<>();     

    List<ArrayList<String>> list=new ArrayList<>();
        list.add(new ArrayList<>(Arrays.asList("a")));
        list.add(new ArrayList<>(Arrays.asList("a,b,c")));
        list.add(new ArrayList<>(Arrays.asList("a,c")));
        list.add(new ArrayList<>(Arrays.asList("c")));
        list.add(new ArrayList<>(Arrays.asList("b,d")));
        list.add(new ArrayList<>(Arrays.asList("b")));

        ArrayList<Integer> value=new ArrayList<Integer>();
        value.add(1);
        value.add(5);
        value.add(3);
        value.add(4);
        value.add(2);
        value.add(1);

        HashMap<ArrayList<String>,Integer> map=new HashMap<ArrayList<String>,Integer>();
        for(int i=0;i<list.size();i++)
        {
            map.put(list.get(i),value.get(i));
        }
        result.add(map);
        System.out.println(result);//output : [{[a]=1, [a,b,c]=5, [b]=1, [c]=4, [a,c]=3, [b,d]=2}]
    }

我得到了输出:

[{[a]=1, [a,b,c]=5, [b]=1, [c]=4, [a,c]=3, [b,d]=2}]

但是,我想按他们的字数来获得排序顺序,例如:

[{[a]=1,[c]=4,[b]=1},{[a,c]=3, [b,d]=2},{ [a,b,c]=5}]

3 个答案:

答案 0 :(得分:0)

您可以使用以下排序:

public static void main(String[] args) throws IOException {
    ArrayList<HashMap<ArrayList<String>, Integer>> result = new ArrayList<>();

    List<ArrayList<String>> list = new ArrayList<>();
    list.add(new ArrayList<>(Arrays.asList("a")));
    list.add(new ArrayList<>(Arrays.asList("a,b,c")));
    list.add(new ArrayList<>(Arrays.asList("a,c")));
    list.add(new ArrayList<>(Arrays.asList("c")));
    list.add(new ArrayList<>(Arrays.asList("b,d")));
    list.add(new ArrayList<>(Arrays.asList("b")));

    List<Integer> value = new ArrayList<>();
    value.add(1);
    value.add(5);
    value.add(3);
    value.add(4);
    value.add(2);
    value.add(1);

    HashMap<ArrayList<String>, Integer> map = new HashMap<>();
    for (int i = 0; i < list.size(); i++) {
        map.put(list.get(i), value.get(i));
    }
    Map<ArrayList<String>, Integer> sorted = map.entrySet()
            .stream()
            .sorted((Map.Entry.<ArrayList<String>, Integer>comparingByValue()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

    System.out.println(map);//output : [{[a]=1, [a,b,c]=5, [b]=1, [c]=4, [a,c]=3, [b,d]=2}]
    System.out.println(sorted);//output : {[a]=1, [b]=1, [b,d]=2, [a,c]=3, [c]=4, [a,b,c]=5}
}

答案 1 :(得分:0)

好的,这就是我认为您需要的:

public static void main(String[] args) {
    List<Map<List<String>, Integer>> mapList = new ArrayList<>();

    put(mapList, Arrays.asList("a"),           1);
    put(mapList, Arrays.asList("a", "b", "c"), 5);
    put(mapList, Arrays.asList("a", "c"),      3);
    put(mapList, Arrays.asList("c"),           4);
    put(mapList, Arrays.asList("b", "d"),      2);
    put(mapList, Arrays.asList("b"),           1);

    System.out.println(mapList); // Output: [{[a]=1, [b]=1, [c]=4}, {[a, c]=3, [b, d]=2}, {[a, b, c]=5}]
}

private static void put(List<Map<List<String>, Integer>> mapList, List<String> words, Integer number) {
    assert !words.isEmpty() : "Must be at least one word in list";

    // First, make sure our list of maps is long enough for the word list we're adding
    while(mapList.size() < words.size()) {
        mapList.add(new HashMap<>());
    }

    // Now, add the words and number to the appropriate map
    mapList.get(words.size() - 1).put(words, number);
}

或者,我们可以构造一个包含所有内容的初始Map,然后按字数对其进行分区并对所得集合进行排序。这种方法意味着,如果您没有任何特定长度的单词列表,则不会将用于保存此类单词列表的空Map添加到结果中(在上述解决方案中,它将是)。此解决方案的代码有点难以理解-您可能需要做汇总阅读:

public static void main(String[] args) {
    Map<List<String>, Integer> initial = new HashMap<>();

    initial.put(Arrays.asList("a"),           1);
    initial.put(Arrays.asList("a", "b", "c"), 5);
    initial.put(Arrays.asList("a", "c"),      3);
    initial.put(Arrays.asList("c"),           4);
    initial.put(Arrays.asList("b", "d"),      2);
    initial.put(Arrays.asList("b"),           1);
    initial.put(Arrays.asList("v", "w", "x", "y", "z"), 99);

    List<Map<List<String>, Integer>> result = new ArrayList<>(
        initial.entrySet() // Get an unordered collection of entries
            .stream()
            .collect(Collectors.groupingBy(
                e -> e.getKey().size(), // Group by word list size...
                TreeMap::new, // ...into a sorted map...
                Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue) // ... collecting all values with the same word count into individual Maps
            ))
            .values() // Construct our ArrayList using the ordered collection of map values
    );

    System.out.println(result); // Output: [{[a]=1, [b]=1, [c]=4}, {[a, c]=3, [b, d]=2}, {[a, b, c]=5}, {[v, w, x, y, z]=99}]
    // Note that the above result doesn't contain an empty Map ('{}') for 4-word lists
}

答案 2 :(得分:0)

这里的主要问题是HashMap没有任何顺序。您可以使用TreeMap(按其键的自然顺序排序),也可以使用预定义的比较器或LinkedHashMap(按插入顺序排序)。

使用TreeMap,只需稍作更改即可获得正确的结果:

List<List<String>> list = Arrays.asList(
        Arrays.asList("a"),
        Arrays.asList("a", "b", "c"),
        Arrays.asList("a", "c"),
        Arrays.asList("c"),
        Arrays.asList("b", "d"),
        Arrays.asList("b"));

List<Integer> value = Arrays.asList(1, 5, 3, 4, 2, 1);

Comparator<List<String>> comparator = Comparator.<List<String>>comparingInt(List::size)
        .thenComparing(List::hashCode);
TreeMap<List<String>, Integer> map = new TreeMap<>(comparator);
for (int i = 0; i < list.size(); i++) {
    map.put(list.get(i), value.get(i));
}

使用比较器,您告诉地图首先按列表的大小排序,如果多个列表的大小相同,则使用hashCode()对其进行排序。结果将如下所示:

{[a]=1, [b]=1, [c]=4, [a, c]=3, [b, d]=2, [a, b, c]=5}