繁体   English   中英

在 Map 中分组键和值

[英]Grouping Keys and Values in Map

我有一个 Map,它以 String 为键,以 String[] 为值。

Map<String,String[]> map = new HashMap<>();
map.put("String1", new String[]{ "abc", "dfe", "new"});
map.put("String8", new String[]{"xyz","hji","new"});
map.put("String2", new String[]{"abc","dfe","old"});
map.put("String3", new String[]{"abc","dfe","past"});
map.put("String5", new String[]{"xyz","hji","ancient"});
map.put("String6",new String[]{"xyz","hji","past"});
map.put("String4", new String[]{"abc","dfe","ancient"});
map.put("String7", new String[]{"xyz","hji","old"});

我想使用值打印地图分组。
值是字符串数组。
String 数组的前两个元素将用于分组。
代码必须在不通过任何过滤器的情况下找到相似的值并按值分组。
最终输出将如下所示:

String1:[{ "abc", "dfe", "new"}]
String2:[{"abc","dfe","old"}]
String3:[{"abc","dfe","past"}]
String4:[{"abc","dfe","ancient"}]
String5:[{"xyz","hji","ancient"}]
String6:[{"xyz","hji","past"}]
String7:[{"xyz","hji","old"}]
String8:[{"xyz","hji","new"}]

如何在 Java 8 中实现这一点?

根据您的输出,您似乎只想根据键进行排序。 所以你可以这样做。 创建一个SortedMap并在构造函数中将当前地图添加到它。

SortedMap<String,String[]> smap = new TreeMap<>(map);
smap.forEach((k,v)-> System.out.println(k + ":" + Arrays.toString(v)));

印刷

String1:[abc, dfe, new]
String2:[abc, dfe, old]
String3:[abc, dfe, past]
String4:[abc, dfe, ancient]
String5:[xyz, hji, ancient]
String6:[xyz, hji, past]
String7:[xyz, hji, old]
String8:[xyz, hji, new]

你可以像这样进行双重分组:

Map<String, String[]> map = new HashMap<>();
map.put("String1", new String[]{"abc", "dfe", "new"});
map.put("String8", new String[]{"xyz", "hji", "new"});
map.put("String2", new String[]{"abc", "dfe", "old"});
map.put("String3", new String[]{"abc", "dfe", "past"});
map.put("String5", new String[]{"xyz", "hji", "ancient"});
map.put("String6", new String[]{"xyz", "hji", "past"});
map.put("String4", new String[]{"abc", "dfe", "ancient"});
map.put("String7", new String[]{"xyz", "hji", "old"});


Map<String, Map<String, List<Map.Entry<String, String[]>>>> collect = map.entrySet()
        .stream()
        .collect(Collectors.groupingBy(x -> x.getValue()[0], Collectors.groupingBy(x -> x.getValue()[1])));

Map<String, String[]> collect1 = collect.values()
        .stream()
        .flatMap(x -> x.values().stream())
        .flatMap(Collection::stream)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

System.out.println(collect1);

如果您只想根据键进行排序,那么您可以使用 Java 8 来完成:

        Map<String, String[]> map = new HashMap<>();
        map.put("String1", new String[]{"abc", "dfe", "new"});
        map.put("String8", new String[]{"xyz", "hji", "new"});
        map.put("String2", new String[]{"abc", "dfe", "old"});
        map.put("String3", new String[]{"abc", "dfe", "past"});
        map.put("String5", new String[]{"xyz", "hji", "ancient"});
        map.put("String6", new String[]{"xyz", "hji", "past"});
        map.put("String4", new String[]{"abc", "dfe", "ancient"});
        map.put("String7", new String[]{"xyz", "hji", "old"});

        map = map.entrySet().stream().sorted(comparingByKey()).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

        map.forEach((s1, strings) -> System.out.println(s1 + " : " + Arrays.toString(strings)));

输出将是:

String1 : [abc, dfe, new]
String2 : [abc, dfe, old]
String3 : [abc, dfe, past]
String4 : [abc, dfe, ancient]
String5 : [xyz, hji, ancient]
String6 : [xyz, hji, past]
String7 : [xyz, hji, old]
String8 : [xyz, hji, new]

同样正如您提到的,您想根据数组的第 2 个元素(值)对地图进行排序,然后您可以尝试比较器:

从值分组数组的第 2 个元素然后排序

    Map<String, String[]> map = new HashMap<>();
    map.put("String1", new String[]{"abc", "dfe", "new"});
    map.put("String8", new String[]{"xyz", "hji", "new"});
    map.put("String2", new String[]{"abc", "dfe", "old"});
    map.put("String3", new String[]{"abc", "dfe", "past"});
    map.put("String5", new String[]{"xyz", "hji", "ancient"});
    map.put("String6", new String[]{"xyz", "hji", "past"});
    map.put("String4", new String[]{"abc", "dfe", "ancient"});
    map.put("String7", new String[]{"xyz", "hji", "old"});

    // Compare based on 1st 2 element oof Array (Map Value)
    Comparator<String[]> byArrayValue = (String[] o1, String[] o2) -> o1[0].concat(o1[1]).compareTo(o2[0].concat(o2[1]));


    // Sort based on 1st 2 element of array
    map = map.entrySet().stream()
            .sorted(Map.Entry.<String, String[]>comparingByValue(byArrayValue))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));


    map.forEach((s1, strings) -> System.out.println(s1 + " : " + String.join(",", strings)));

输出将基于值数组的第 2 个元素:

String4 : [abc, dfe, ancient]
String3 : [abc, dfe, past]
String2 : [abc, dfe, old]
String1 : [abc, dfe, new]
String8 : [xyz, hji, new]
String7 : [xyz, hji, old]
String6 : [xyz, hji, past]
String5 : [xyz, hji, ancient]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM