码:

   Map<Integer, HashSet<String>> test = new TreeMap<>();
    test.put(1, new HashSet<>());
    test.put(2, new HashSet<>());
    test.put(3, new HashSet<>());
    test.put(4, new HashSet<>());

    test.get(1).add("1");
    test.get(2).add("2");
    test.get(3).add("2");
    test.get(4).add("3, 33");

    //get value of treemap and get rid of the duplicate by using distinct and printout
    //at the end
    test.values().stream().distinct().forEach(i -> System.out.println(i));


输出:

[1]
[2]
[3, 33]


我的问题是如何在不重复值的情况下同时打印键和值?

预期结果:

  1= [1]
  2= [2]
  3= [3, 33]


我什至尝试下面的代码,但是它给了我带有重复值的树形图:

码:

   List<Map.Entry<Integer, HashSet<String>>> list = new ArrayList<>();
   list.addAll(test.entrySet());
   list.stream().distinct().forEach( i -> System.out.println(i));


输出:

1=[1]
2=[2]
3=[2]
4=[3, 33]

最佳答案

test.entrySet().stream()
        .collect(
                Collectors.toMap(
                        Map.Entry::getValue,
                        x -> x,
                        (a, b) -> a
                )
        ).values()
        .forEach(System.out::println);


编辑:

说明:此片段将获取条目流,并将它们放入值到条目的映射中,同时丢弃重复项(有关Collectors#toMap的信息,请参见javadoc)。然后,它将该映射的值作为一个集合。结果是由Map.Entry::getValue区分的地图条目的集合。

编辑2:

从您的评论中,我认为我了解您正在尝试做的事情。您将此TreeSet用作基于1的列表,并且希望键在删除重复值时折叠。那是对的吗?也许您可以解释为什么要这样做,而不仅仅是使用列表。

流不是很适合这种方法,因此它不是很漂亮,但是您可以使用:流处理值,消除重复项,收集到列表中,然后将列表转回到地图中。

test.values().stream()
        .distinct()
        .collect(
                Collectors.collectingAndThen(
                        Collectors.toList(),
                        lst -> IntStream.range(0, lst.size()).boxed().collect(
                                Collectors.toMap(i -> i + 1, i -> lst.get(i))
                        )
                )
        ).entrySet().forEach(System.out::println);

output:
 1=[1]
 2=[2]
 3=[3, 33]

09-07 15:15
查看更多