Java 在树映射上应用Distinct函数

Java 在树映射上应用Distinct函数,java,lambda,distinct,java-8,treemap,Java,Lambda,Distinct,Java 8,Treemap,代码: 我的问题是如何在没有重复值的情况下同时打印出键和值? 预期结果: [1] [2] [3, 33] 我甚至尝试了下面的代码,但它给出了带有重复值的树状图: 代码: Map test=newtreemap(); test.put(1,新HashSet()); test.put(2,新HashSet()); test.put(3,新HashSet()); test.put(4,新HashSet()); 测试。获取(1)。添加(“1”); 测试。获取(2)。添加(“2”); 测试。获取(3)。

代码:

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

预期结果:

[1]
[2]
[3, 33]
我甚至尝试了下面的代码,但它给出了带有重复值的树状图:

代码:

Map test=newtreemap();
test.put(1,新HashSet());
test.put(2,新HashSet());
test.put(3,新HashSet());
test.put(4,新HashSet());
测试。获取(1)。添加(“1”);
测试。获取(2)。添加(“2”);
测试。获取(3)。添加(“2”);
测试。获取(4)。添加(“3,33”);
整数计数=0;
HashSet distinctValues=新HashSet();
test.entrySet().stream().forEach(条目->{
HashSet entryValues=新HashSet();
entryValues.addAll(entry.getValue());
//忽略已处理的任何值
entryValues.removeAll(distinctValues);
如果(!entryValues.isEmpty()){
System.out.println(++count+“=”+entryValues);
distinctValues.addAll(entryValues);
}
});
编辑:

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

编辑2:

从你的评论中,我想我明白你想做什么。您正在将此树集用作基于1的列表,并希望在删除重复值时键折叠。对吗?也许你可以解释你为什么要这样做,而不是仅仅使用一个列表

流不太适合这种方法,所以这不太合适,但现在可以这样做:流化值,消除重复项,收集到列表中,然后将列表返回到映射中

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

您的问题有点混乱,因为您说您希望键具有不同的值,但重复的值显然具有重复的键。在您的示例中,由于值
2
在源映射中出现两次,具有键
2
3
,因此不清楚为什么希望值
2
使用键
2

以下代码将收集重复项的所有密钥:

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]
它将打印:

test.entrySet().stream().collect(Collectors.groupingBy(
     Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
  .forEach((value,keys) -> System.out.println(keys+"\t= "+value));

作为您的示例地图。由您从钥匙列表中选择钥匙
2
[2,3]如果您有选择的规则。

我想应用lambda抱歉,我刚刚意识到我误解了您的问题。您只需要跟踪到目前为止处理的一组值-请参阅编辑后的回答我非常感谢您的回答,稍后我会看一看,但我的问题是如何使用Java8来实现这一点,我认为在这种情况下,使用lambdas不会带来任何好处。它不是for循环,而是
test.entrySet().stream().forEach(entry->
其他一切都是一样的为什么
3=[3,33]
?发生了什么事
4
?对于
2
,应该保留哪个键?这是预期的结果。正如您所看到的,2和3的值与2的值相同。甚至可以得到我的预期结果吗?不,考虑到您需要条目的键和值,您的预期结果没有多大意义。
[3,33]
应映射到
4
。您必须定义映射的行为方式。那么,定义映射的行为方式是什么意思呢?目前,您要求我如何在不存在重复值的情况下同时打印出键和值,这与您的预期结果并不匹配。请给我们一些这样的内容。因此,没有re没有重复值?你能把这段代码的结果公布出来吗?我不在编译器附近,但它应该打印1=[1]2=[2]4=[3,33]@KickButtowski在你的设置中,你有
test.get(4).add(“3,33”);
,所以它会打印4=[3,33].钥匙不可能变成3而不是4吗?请解释您的方法,以便我可以接受it@KickButtowski你能解释一下你期望3从哪里来吗?在原始树形图中,集合[“3,33”]与键4相关联。
1=[1]
2=[2]
3=[2]
4=[3, 33]
   Map<Integer, HashSet<String>> test = new TreeMap<>();
        test.put(1, new HashSet<String>());
        test.put(2, new HashSet<String>());
        test.put(3, new HashSet<String>());
        test.put(4, new HashSet<String>());

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

    int count = 0;
    HashSet<String> distinctValues = new HashSet<>();
    test.entrySet().stream().forEach(entry -> {
      HashSet<String> entryValues = new HashSet<>();
      entryValues.addAll(entry.getValue());
      // ignore any values you've already processed
      entryValues.removeAll(distinctValues);
      if (!entryValues.isEmpty()) {
          System.out.println(++count + " = " + entryValues);
          distinctValues.addAll(entryValues);
      }
    });
test.entrySet().stream()
        .collect(
                Collectors.toMap(
                        Map.Entry::getValue,
                        x -> x,
                        (a, b) -> a
                )
        ).values()
        .forEach(System.out::println);
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]
test.entrySet().stream().collect(Collectors.groupingBy(
     Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
  .forEach((value,keys) -> System.out.println(keys+"\t= "+value));
 [1]    = [1]
 [2, 3] = [2]
 [4]    = [3, 33]