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]