Java17中使用Stream(8->11遇到的问题)

一、对于Collect操作的变化
Collectors.toUnmodifiableList()支持了不可变的搜集器
Stream.toList()支持了转List的操作符
二、实际的使用
用法 可变性 容null性
Collectors.toList() 可变 可null
Collectors.toUnmodifiableList() 不可变 不可null
Stream.toList() 不可变 可null
demo:

@ExtendWith(MockitoExtension.class)
class DemoTest {
    
    
    /**
     * 正常情况
     */
    @Test
    void test1() {
    
    
        var source = new ArrayList<String>();
        source.add("1");
        source.add("2");
        source.add(null);
        // 正常数据 可修改,可处理空数据
        List<String> list1 = source.stream().collect(Collectors.toList());
        list1.add("4");
        // UnmodifiableList 引用了java.util.ImmutableCollections,不支持null
        assertThatThrownBy(() -> {
    
    
            source.stream().collect(Collectors.toUnmodifiableList());
        }).isInstanceOf(NullPointerException.class);
        List<String> list2 = source.stream().filter(Objects::nonNull).collect(Collectors.toUnmodifiableList());
        assertThatThrownBy(() -> {
    
    
            list2.add("4");
        }).isInstanceOf(UnsupportedOperationException.class);
        // toList操作符 不支持修改,不能存null
        List<String> list3 = source.stream().toList();
        assertThatThrownBy(() -> {
    
    
            list3.add("4");
        }).isInstanceOf(UnsupportedOperationException.class);
    }
}

三、范型遇到的问题
在Java8中对于Raw type的容器对象,为了方便序列化的读写操作会将其转换成String或者二进制数据,所以经常会有下面的操作

List rawList = new ArrayList();
rawList.add("1");
rawList.add("2");
List<String> ret = rawList.stream().map(Object::toString).collect(Collectors.toList());


这样拿到ret之后可以再进行整体的读写操作,其实rawList.stream()这块的linq操作执行的结果是产生了一个Stream的数据流,交给map变换成Stream
但是同一段代码在Java17中会直接得到一个类型转换错误

List<String> ret = Stream.of("null",123)
       .map(Object::toString).collect(Collectors.toList());

其实整件事情的重点在于对范型的理解和java 11引入的var关键字

java确实存在范型擦出,在编译之后处理的都是Object,但是无论从字节码的角度看,还是从语义的角度看List和List是有区别的
java11由于引入了var,实际上对于List和List的stream操作的语义推断返回值是不同的,前者返回的Stream,后者返回的是Stream
明确了上述两点,再来看下下面的代码


List tt = new ArrayList();
tt.add("111");
tt.add("222");
// Java8下编译错误,两者都是编译错误,因为collect(Collectors.toList())返回的是Object
List<String> e1 = tt.stream().map(param -> param.toString()).collect(Collectors.toList());
List e2 = tt.stream().map(param -> param.toString()).collect(Collectors.toList());
// Java8下正确编译
Stream<Object> s8 = tt.stream();
List<String> ret8 = s8.map(Object::toString).collect(Collectors.toList());
// Java11下正确编译,但是提示raw type
Stream<Object> s11 = paramJsonArray.stream();
List<String> ret11 = s11.map(Object::toString).collect(Collectors.toList());

猜你喜欢

转载自blog.csdn.net/Climbman/article/details/130788765
今日推荐