java - 流与。 Map 的 entrySet 中的迭代器 - Java 8

标签 java java-8 iterator java-stream entryset

据我了解,以下代码应该打印 true,因为 StreamIterator 都指向第一个元素。

但是,当我运行以下代码时,它正在打印 false:

final HashMap<String, String> map = new HashMap<>();
map.put("A", "B");
final Set<Map.Entry<String, String>> set = Collections.unmodifiableMap(map).entrySet();
Map.Entry<String, String> entry1 = set.iterator().next();
Map.Entry<String, String> entry2 = set.stream().findFirst().get();
System.out.println(entry1 == entry2);

造成这种不同行为的原因可能是什么?

最佳答案

这两个条目都指向 Map 的同一个逻辑条目(其键为“A”,值为“B”)。但是,它们不是同一个实例。

如果您在 Collections.unmodifiableMap(map) 的实现中深入挖掘,您将看到迭代 Collections 返回的 map 的 entrySet .unmodifiableMap(map) 返回一个新的 Map.Entry 包装原始可修改条目:

public Map.Entry<K,V> next() {
  return new UnmodifiableEntry<>(i.next());
}

我假设当您调用 set.stream().findFirst().get() 时也会创建一个新实例 Map.Entry 实例,所以两种方法返回不同的实例。

即使你调用同一个方法两次你也会得到不同的实例,即下面的代码也会打印 false:

Map.Entry<String, String> entry1 = set.iterator().next();
Map.Entry<String, String> entry2 = set.iterator().next();
System.out.println(entry1 == entry2);

另一方面,如果直接从原始HashMap中获取entry,则会得到true:

Map.Entry<String, String> entry1 = map.entrySet ().iterator().next();
Map.Entry<String, String> entry2 = map.entrySet ().stream().findFirst().get();
System.out.println (entry1==entry2);

如果这种情况下条目没有被新实例包装,那么 entrySet ().iterator().next()entrySet ().stream().findFirst( ).get() 返回相同的实例。

关于java - 流与。 Map 的 entrySet 中的迭代器 - Java 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44691577/

相关文章:

php - 为什么 isDot() 对我失败? (PHP)

java - 为什么此代码不会导致 ConcurrentModificationException?

java - 尝试在空对象引用上调用虚拟方法“boolean java.util.ArrayList.add”

java - Spring JdbcTemplate.update() 没有更新行

java - @MustOverride 注释?

exception - 处理java8中CompletableFuture中的运行时异常

java - 如果使用自定义比较器创建,则为 SortedMap 生成的流的流特征可能无法排序

java - Jackson 将 ISO8601 格式的日期时间反序列化为 Java8 Instant

c++ - 调用对象 vector 的成员函数

java - g选择:如何从一个列表中提取值并从另一个列表中显示选项?