Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Collections.UnmodifiableMap.UnmodifiableEntrySet重写stream()方法?_Java_Oop_Collections_Java Stream_Overriding - Fatal编程技术网

Java 为什么Collections.UnmodifiableMap.UnmodifiableEntrySet重写stream()方法?

Java 为什么Collections.UnmodifiableMap.UnmodifiableEntrySet重写stream()方法?,java,oop,collections,java-stream,overriding,Java,Oop,Collections,Java Stream,Overriding,在查看源代码时,我可以看到stream()方法已在Collections.UnmodifiableMap.UnmodifiableEntrySet中被重写。但是代码似乎与Collection.stream()相同,除了Collections.UnmodifiableMap.UnmodifiableEntrySet.stream()中的返回类型更具体地说是stream,而不仅仅是Collection.stream()中的stream spliterator()方法在这两个类中是不同的,但是即使st

在查看源代码时,我可以看到
stream()
方法已在
Collections.UnmodifiableMap.UnmodifiableEntrySet
中被重写。但是代码似乎与
Collection.stream()
相同,除了
Collections.UnmodifiableMap.UnmodifiableEntrySet.stream()
中的返回类型更具体地说是
stream
,而不仅仅是
Collection.stream()
中的
stream

spliterator()
方法在这两个类中是不同的,但是即使
stream
没有被重写,我认为如果对象的类型是
UnmodifiableEntrySet
,那么
UnmodifiableEntrySet.spliterator()
将从
Collection.stream()
调用

那么,
方法被重写有什么原因吗

Collection.java

@覆盖
默认拆分器拆分器(){
返回拆分器。拆分器(this,0);
}
默认流(){
返回StreamSupport.stream(spliterator(),false);
}
Collections.UnmodifiableMap.UnmodifiableEntrySet.java

@SuppressWarnings(“未选中”)
公共拆分器拆分器(){
返回新的不可修改EntrySetSpliterator(
(拆分器)c.拆分器();
}
@凌驾
公共流(){
返回StreamSupport.stream(spliterator(),false);
}

在将
Collections.java
的内容复制到一个新类
CollectionsCopy.java
之后,我尝试从
UnmodifiableEntrySet
中删除
stream
方法,然后进行了一些调试并得到了答案


UnmodifiableEntrySet
扩展了
UnmodifiableSet
,它扩展了
UnmodifiableCollection
,后者反过来实现了
Collection
。由于
UnmodifiableCollection
下面有一个字段
final Collection,Java文档/程序来自openjdk 14 2020-03-17

重写
spliterator
stream
的主要原因是为了确保
UnmodifiableEntrySet
的条目不被修改。 从
UnmodifiableEntrySet
的注释中:

除了不可修改的集合作为映射之外,我们还需要这个类。条目本身允许通过其setValue操作修改支持映射。这个类很微妙:有许多可能的攻击必须被阻止

首先,
UnmodifiableEntrySet
扩展了
UnmodifiableSet
,它扩展了
UnmodifiableCollection
。 在
UnmodifiableCollection
中,代理模式用于避免修改backing
Collection
c,大多数方法只调用backing
Collection
方法,如
spliterator
stream

@覆盖
公共拆分器拆分器(){
返回(拆分器)c.拆分器();
}
@抑制警告(“未选中”)
@凌驾
公共流(){
返回(Stream)c.Stream();
}

因此,如果
UnmodifiableEntrySet
没有覆盖这些方法,则行为将遵循
UnmodifiableCollection
实现,并且支持项将被公开,并且可以通过修改

因此,
spliterator
stream
方法被覆盖,并且引入了
UnmodifiableEntrySetSpliterator
,以使用
UnmodifiableEntry
包装对备份条目的所有访问,确保无法修改条目

为什么
不可修改的集合
覆盖
? 似乎没有必要在
不可修改的集合
中重写
,因为我们可以在
集合
中使用默认实现(只需通过
拆分器创建流
)。 但是作者决定使用backing
Collection c
stream
方法覆盖
stream
,其中一个可能的原因是backing
Collection
出于性能原因可能会覆盖
stream
方法,例如
Collections.CopiesList
,或者它的
spliterator
方法不符合

当spliterator()方法无法返回不可变、并发或后期绑定的拆分器时,应重写此方法。(有关详细信息,请参见拆分器()


因为
UnmodifiableEntrySet
是一组
条目
,而
集合
是通用的。“我不知道是什么把你弄糊涂了。”“是的。我的问题是,如果方法体与集合完全相同,为什么
UnmodifiableEntrySet
应该重写
stream()
方法。stream()
@AniketSahrawat经过一些调试后,我多少能找到一个解决方案。@Gautham-
stream
不是
流。另一个例子是
List
不是
List
。我昨天误读了你的问题。如果您查看一下
流的实现,您会注意到它在7个位置被覆盖。相关覆盖位于
UnmodifiableCollection
中,然后再次位于
UnmodifiableEntrySet
UnmodifiableCollection#stream
基本上是将调用委托给传递的
Collection
。如果
UnmodifiableEntrySet
中没有重写,则调用将委托给原始
集合(该集合是可变的)。这解释了大部分调用。但我没有什么疑问这就是我试过的。在我的
CollectionsCopy
类中,我已经从
UnmodifiableEntrySet
UnmodifiableCollection
中删除了覆盖的
流。然后我尝试了
unmodifiableMap.entrySet().stream().findFirst().orElse(null)
。这实际上返回了一个不可变的条目。如果我
public Stream<E> stream() {
    return (Stream<E>)c.stream();
}
super((Set)s);