【问题标题】:How can I get the sorted arrayList in HashMap? [closed]如何在 HashMap 中获取已排序的数组列表? [关闭]
【发布时间】:2019-08-29 08:32:07
【问题描述】:

我已经尝试了以下 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}]

【问题讨论】:

  • A HashMap 没有任何订单 - 如果您想要有序地图,请查看 https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
  • 您最初的要求是什么,我们可以找到另一种合适的数据结构而不是这个?您可以使用有关您的意图的更多信息来编辑问题吗?
  • 根据括号,您想要的输出[{[a]=1,[c]=4,[b]=1},{[a,c]=3, [b,d]=2},{ [a,b,c]=5}] 似乎是三个地图的列表。这是为什么呢?
  • 在这个问题的当前格式中,实际上并不清楚您实际上想要实现什么:您发布的一些代码显然不能满足您的要求,而且并不明显它的变体将如何(您提到“按字数计算”,但您发布的任何代码行似乎都没有尝试计算字数?)。你能用几句话解释你想要达到的目标:你需要将哪些数据作为输入以及如何输出?

标签: java arraylist hashmap


【解决方案1】:

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

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】:

    您可以使用以下排序:

    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}
    }
    

    【讨论】:

    • 高效。但这似乎不是预期的输出。
    • 正如我得到作者的问题一样。最初的要求有点模棱两可。 :)
    【解决方案3】:

    这里的主要问题是HashMap 没有任何顺序。您可以使用 eiter a 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}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-18
      • 2011-09-19
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      相关资源
      最近更新 更多