Lui*_*ese 7 java eclipse generics java-8 java-stream
有人可以帮助我理解为什么这段代码的行为如评论中所述
// 1) compiles
List<Integer> l = Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList<Integer>::addAll);
/*
* 2) does not compile
*
* Exception in thread "main" java.lang.Error: Unresolved compilation problems:
* Type mismatch: cannot convert from Object to <unknown>
* The type ArrayList does not define add(Object, Integer) that is applicable here
* The type ArrayList does not define addAll(Object, Object) that is applicable here
*/
Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
// 3) compiles
Stream.of(1, 2, 3).collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
/*
* 4) does not compile
*
* Exception in thread "main" java.lang.Error: Unresolved compilation problems:
* Type mismatch: cannot convert from Object to <unknown>
* The type ArrayList does not define add(Object, Integer) that is applicable here
* The type ArrayList<Integer> does not define addAll(Object, Object) that is applicable here
*/
Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList<Integer>::addAll);
Run Code Online (Sandbox Code Playgroud)
它显然与泛型方法中的类型定义有关,它是必须以某种方式提供的信息......但为什么它是强制性的?在哪里,怎么样,语法,我应该从方法签名想通了of()
和collect()
?
public static<T> Stream<T> of(T... values) {...}
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
Run Code Online (Sandbox Code Playgroud)
虽然这不是一个分析http://download.oracle.com/otndocs/jcp/lambda-0_9_3-fr-eval-spec/index.html上的Lambda规范的答案,但我试图找出它依赖的内容.
从Stream
类中复制两个方法:
static class Stream2<T> {
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream2<T> of(T... values) {
return new Stream2<>();
}
public <R> R collect( Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner){return null;}
}
Run Code Online (Sandbox Code Playgroud)
这编译:
Stream2.of(1,2,3).collect(ArrayList::new, ArrayList::add, ArrayList::addAll );
Run Code Online (Sandbox Code Playgroud)
喜欢OP(2).
现在collect
通过将第一个参数移动到第三个位置来更改方法
public <R> R collect(BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner,
Supplier<R> supplier
){return null;}
Run Code Online (Sandbox Code Playgroud)
这仍然有效(5):
Stream2.of(1,2,3).collect(ArrayList::add, ArrayList::addAll,ArrayList::new );
Run Code Online (Sandbox Code Playgroud)
这也有效(6):
Stream2.of(1,2,3).collect(ArrayList::add, ArrayList::addAll,ArrayList<Integer>::new );
Run Code Online (Sandbox Code Playgroud)
这些不起作用(7,8):
Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList::addAll,ArrayList::new );
Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList<Integer>::addAll,ArrayList::new );
Run Code Online (Sandbox Code Playgroud)
但这再次起作用(9):
Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList<Integer>::addAll,ArrayList<Integer>::new );
Run Code Online (Sandbox Code Playgroud)
所以我想当供应商使用显式类型参数进行注释时,它似乎有效.当只有消费者时,却没有.但也许其他人知道为什么会有所作为.
编辑:尝试使用TestList
,它甚至更奇怪:
public class StreamTest2 {
public static void main(String[] args) {
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll);
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll2);
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll3);
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll4);
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll5);
Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll6);
}
}
class TestList<T> extends AbstractList<T> {
@Override
public T get(int index) {
return null;
}
@Override
public int size() {
return 0;
}
@Override
public boolean addAll(Collection<? extends T> c) {
return true;
}
public boolean addAll2(TestList<? extends T> c) {
return true;
}
public boolean addAll3(Collection<T> c) {
return true;
}
public boolean addAll4(List<? extends T> c) {
return true;
}
public boolean addAll5(AbstractList<? extends T> c) {
return true;
}
public boolean addAll6(Collection<? extends T> c) {
return true;
}
@Override
public boolean add(T e) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
addAll
不起作用,但是addAll2
- 6
做的工作.即使是addAll6
作品,也与原作相同addAll
.
归档时间: |
|
查看次数: |
2354 次 |
最近记录: |