Java基础篇——集合进阶(三)

不可变集合

不可变集合:不能修改长度,和内容。

应用场景:不想让别人修改集合中的内容,只能进行查询,保证安全性。

方法:调用集合中的of方法。对map调用copyOf方法。

细节1:当我们要获取一个不可变的Set集合时,里面的参数一定要保持不重复,否则会报错。

细节2:当我们要获取一个不可变的Map集合时,除了键要保持不重复之外, 只能传递不超过20个参数(10个键值对)。

  • 底层:因为一个键值对有两个值,而形参中最多只能写一个可变参数

细节3:当我们要获取一个不可变的Map集合时,可以先对map集合调用entrySet方法把键值对整体,作为对象存储到Set集合当中,然后把对这个Set集合调用toArray方法转成数组,最后把这个数组传递给ofEntries即可,因为可变参数本质也是一个数组。

Stream流

流:类似工厂流水线,经历消毒-密封-包装等步骤。

步骤:

  • 先得到Stream流
  • 采用Stream流中的API操作,包括中间方法(方法结束后还可以调用其他方法)和终结方法(方法结束后不能再调用其他方法,如输出打印)
Stream流获取方法

单列集合,调用collection中的默认方法stream方法

        ArrayList<String> al = new ArrayList<>();

        al.add("111");
        al.add("222");
        al.add("333");
		//调用collection中默认方法stream方法获取stream流
        Stream<String> stream1 = al.stream();
		//用forEach遍历stream流中的元素
        stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

		//链式编程+Lambda表达式
		al.stream().forEach(s->System.out.println(s));
  • 双列集合,不能获取。需要通过keySet或者entrySet转换
  • 数组,可以使用数组工具类Arrays中的stream方法
  • 零散数据,用Stream接口中的静态方法of进行处理,必须是同一数据类型。

细节:of方法的形参是一个可变参数,可以传递多个零散数据,也可以传递数组(因为可变参数底层就是数组)。但是数组中元素必须是引用数据类型,才能获取到数组中每个元素;如果数组中元素是基本数据类型,那么传递的数组就会被当成of方法的一个数据。底层是因为of方法的形参是泛型,因此只能传递包装类和对象。

Stream流的中间方法

注意:

  • 调用中间方法会返回新的Stream流,原来的Stream流只能使用一次,用完就关闭了。因此建议用链式编程
  • 修改Stream流中的数据不会影响原来集合或数组中的数据

Stream流的终结方法

 

终结方法:这些方法的返回值均不是Stream流,因此后续不能再调用其他方法,因此是终结方法。

collect方法

  • 把收集流中的数据放到map集合中:收集到map集合中,键不能重复
  • collect方法的形参需要传递一个Collector类型的对象,通过调用Collectors类中的静态方法toMap,就可以生成这个对象。
  • 在toMap方法中需要传递Function接口的两个实现类对象,第一个Function接口泛型的第一个String表示Stream流中的数据类型是String,第二个String表示键的数据类型是String;第二个Function接口泛型的第一个String同理,第二个Integer表示值的数据类型是Integer

方法引用

方法引用:把已有的方法拿过来用,当做函数式接口中抽象方法的方法体。

  • 应用背景:也就是我知道这里有一个函数式接口,但是我不想自己写方法体了,想直接用别人写好的,就引用别人的当作自己的方法体。

方法引用注意事项:

  • 引用处必须是函数式接口
  • 被引用的方法必须已经存在
  • 被引用方法功能要能满足需求(废话)
  • 被引用方法的形参和返回值需要和抽象方法一致。举例如下:

 

 方法引用的分类
引用静态方法

格式:类名::静态方法

Integer::parseInt

举例:假设一个集合中有五个字符串类型的整数,把他们转换成Integer类型输出出来。

  • 传统思路:把集合的数据添加到Stream流当中,然后用中间方法map进行数据类型的转换,再用终结方法forEach打印。

  • 利用方法引用:因为map形参是一个函数式接口的实现类对象,因此可以直接引用parseInt方法,正好需求都是想要把String类型转换成int类型

引用成员方法

格式:

  • 为什么引用处不能是静态方法:因为在静态方法中没有this关键字。比如在main方法当中引用,就是在静态方法中引用,此时`this::方法名`就会出错。理解:this关键字指代当前对象,而静态方法优于任何对象出现,不用创建对象,那么,既然都不用创建对象,自然就没有“当前对象”这个概念了。因此,this关键字无法在static方法中使用就解释得通了。
  • 如果想在本类的静态方法中,调用本类的非静态方法呢?只能在本类的静态方法中,创建一个本类的对象,再通过这个对象去调用本类的静态方法。 

练习:

传统思路:把集合中的数据转换成Stream流,然后用中间方法filter方法进行过滤,最后用终结方法forEach打印

  • 方法引用:首先中间方法处形参需要传递函数式接口Predicate的实现类对象,而且假设存在一个类,这个类当中有一个成员方法,形参是字符串,返回值是布尔值,方法中处理的规则和我的需求一样,就可以使用方法引用。但实际上不存在这个方法,因此这里自己写一个类和其中的成员方法。

 引用构造方法

练习: 

传统思路:生成Stream流,然后用map类型进行数据转换,然后在函数式接口的实现类的对象中重写方法,实现这个从String到Student的过程。

方法引用:生成Stream流,然后用map类型进行数据转换,但我不想重写方法,可以在函数式接口处直接引用构造方法,但是想引用的构造方法形参是String,返回值是Student,没有这个构造方法。那么可以自行创建这个构造方法。我要引用的这个构造方法,形参是集合中的String,返回值是Student,如何实现这个过程是一个难点,看自己本事。

引用的构造方法如下:

因为这部分内容草草就过了,笔记做的比较粗糙~

学习资料:黑马程序员

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值