Stream流和方法引用

1. Stream流

1.1. Stream流引入

Stream流完全不是I/O流,按照流水线处理方式来考虑代码中的思想。
JDK1.8 之后,我们拥有了Lambda表达式,让代码的中心偏向解决实际问题,直到重点,
可以提高效率。
Stream流中使用了大量Lambda表达式,利用Lambda操作 方式,提供开发效率

1.2 传统遍历方式和Stream类处理方式对比

public class Demo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>() ;
        list.add("李渊") ;
        list.add("李世民") ;
        list.add("李隆基") ;
        list.add("李隆飞") ;
        list.add("武则天") ;
        list.add("段段") ;
        ArrayList<String> list1 = new ArrayList<>() ;
        for (String s : list) {
            if (s.contains("李")) {
                list1.add(s) ;
            }
        }
        System.out.println(list1);
        ArrayList<String> list2 = new ArrayList<>() ;
        for (String s : list1) {
            if (3 == s.length()) {
                list2.add(s) ;
            }
        }
        for (String s : list2)
        System.out.println(s);
    }
}
public class BetterDemo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>() ;
        list.add("李渊") ;
        list.add("李世民") ;
        list.add("李隆基") ;
        list.add("李隆飞") ;
        list.add("武则天") ;
        list.add("段段") ;
        /**
         *  使用stream流对Demo1进行优化
         */
        list.stream()
                .filter(s -> s.contains("李"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));
    }
}

1.3 Stream流对应的思想

流水线: 原材料从头到尾只会占用一份空间,中间的过程中不会占 用空间。最后生成一个结果。
Stream流有一些特征:
1. 带有很多Stream流操作的方法, filter,limit, map,sorted,skip…这些方法大多是都会使用到函数式接 口,有lambda表达式
2. 整个Stream流模型操作过程中,只有执行到count, foreach这些方法,操作真正的执行中的模型,如果不存在结 果导向,中间的所有操作是无效的,这里得益于Lambda表达式的延后性
3. Stream流是存在一定的管道性 Pipelining 流水线

1.4 获取Stream流

java.util.stream.Stream JDK1.8的新特征
1. 所有的Collection集合都有对应的Stream();
2. 可以通过Stream类中的static Stream of()获取
static Stream of(T… t); static Stream of(T t);

public class Demo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>() ;
        Stream<String> stream1 = list.stream() ;
        Set<String> set = new HashSet<>() ;
        Stream<String> stream2 = set.stream();
        //只要是connector单列集合都可以用stream()方法直接转换为Stream流
        Map<String , String> map = new HashMap<>() ;
        Stream<String> stream3 = map.keySet().stream() ;
        Stream<String> stream4 = map.values().stream() ;
        Stream<Map.Entry<String , String>> stream5 = map.entrySet().stream();
        //Map要先转换成键,值或者键值对等单列集合在调用stream()方法转换为Stream流
        Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5);
        Integer[] arr1 = {1,2,3,4,5,6} ;
        Stream<Integer> stream7 = Stream.of(arr1);
        String[] arr2 = {"飞哥" , "羽羽" , "段段"} ;
        Stream<String> stream8 = Stream.of(arr2);
        //使用Stream接口中的静态方法将数组装换为Stream流
        //把数组转换成Stream流
    }
}

1.5 Stream常用方法

延迟方法:
返回值类型依然是Stream接口本身,并没有影响我们操 作真正的资源
允许链式操作,
例如 filter(XXX).limit(XXX).sorted(XXX).
终结方法: 返回值类型不是Stream接口本身,要么处理数据,要么返回其他类型数据,并且不再支持Stream流对象链式操作, count,foreach

1.5.1 foreach方法

forEach()方法将stream流中的数据进行遍历
返回值不再是stream流
是一个终结流方法
forEach()方法中的参数为Consumer函数式接口

package com.my.demo1;

import java.util.stream.Stream;
/**
 *  forEach()方法将stream流中的数据进行遍历
 *  返回值不再是stream流
 *  是一个终结流方法
 */
public class Demo3 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("飞哥", "羽羽", "段段");
        //流中的forEach方法对流中的数据进行遍历
        //forEach()方法中的参数为Consumer函数式接口
        //可以用lambda表达式书写
        stream.forEach((s -> System.out.println(s)));
    }
}

1.5.2 filter方法

filter方法将一个stream流中的数据进行过滤
返回值仍然是一个stream流
filter() 方法中的参数为Predicate函数式接口

package com.my.demo1;

import java.util.stream.Stream;
/**
 *  filter方法将一个stream流中的数据进行过滤
 *  返回值仍然是一个stream流
 */
public class Demo4 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("李隆基", "李隆飞", "杨玉环", "武则天");
        Stream<String> stream1 = stream.filter((s -> s.startsWith("李"))) ;
        stream1.forEach((s -> System.out.println(s)));

        //stream.forEach(s -> System.out.println(s));
        // 报错!!!
        //一个stream流只能消费一次,第一个stream使用过后就关闭了,所以就不能再调用方法了
    }
}

1.5.3map()方法

map()方法将一种stream流转换为另一种stream流
返回值仍然是一个stream流
map()方法中的参数为Function函数式接口

package com.my.demo1;

import java.util.stream.Stream;
/**
 *  map()方法将一种stream流转换为另一种stream流
 *  返回值仍然是一个stream流
 */
public class Demo5 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("1", "2", "3", "4");
        Stream<Integer> integerStream = stream.map((s -> Integer.parseInt(s)));
        integerStream.forEach((s) -> System.out.println(s));
    }
}

1.5.4count()

count()方法用于统计stream流中的元素个数
返回值不再是一个Stream流,是一个long类型数据
是一个终结流方法

package com.my.demo1;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 *  count()方法用于统计stream流中的元素个数
 *  返回值不再是一个Stream流,是一个long类型数据
 *  是一个终结流方法
 */
public class Demo6 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>() ;
        list.add(1) ;
        list.add(2) ;
        list.add(3) ;
        list.add(4) ;
        list.add(5) ;
        Stream<Integer> stream = list.stream();
        System.out.println(stream.count());
    }
}

1.5.5limit(long maxSize)方法

limit(long maxSize)方法是对流中的元素进行截取
返回值仍然是一个stream流,可以进行链式操作

package com.my.demo1;

import java.util.stream.Stream;

public class Demo7 {
    /**
     *  limit(long maxSize)方法是对流中的元素进行截取
     *  返回值仍然是一个stream流,可以进行链式操作
     */
    public static void main(String[] args) {
        String[] strings = {"飞哥" , "羽羽" , "小明" , "段段"};
        Stream<String> stream = Stream.of(strings);
        Stream<String> stream1 = stream.limit(3);
        stream1.forEach(s -> System.out.println(s));

    }
}

2. 方法引用

2.1 Lambda冗余问题以及方法引用初识

public class Demo11 {
    public static void main(String[] args) {
        printString((s) -> System.out.println(s));
        printString(System.out::println);

    }
    public static void printString(FunctionIn1 fun) {
        fun.print("飞哥");
    }
}

2.2 方法引用小要求

  1. 明确对象 对象 ==> 调用者 类对象,类名,super,this,构造方法,数组构造方法
  2. 明确的执行方法 该方法只有名字不需要显式出现参数
  3. 需要处理的数据 【联想,推导,省略】
  4. :: 方法引用格式

2.3 通过类对象来执行方法引用

  1. 明确对象 类对象
  2. 明确执行的方法 自定义
  3. 处理的数据 简单要求为String类型
public class Demo12 {
    public static void main(String[] args) {
//        printString((s -> {
//            MethodDemo1 methodDemo1 = new MethodDemo1();
//            methodDemo1.printUppercase(s);
//        }));
        /**
         *  使用方法引用对lambda表达式进行优化
         */
        printString(new MethodDemo1()::printUppercase);
    }
    public static void printString(FunctionIn1 fun){
        fun.print("aaaddd");
    }
}

2.4 通过类名来执行方法引用

public class Demo13 {
    public static void main(String[] args) {
//        int num = test(-10 , (n) ->{
//            return Math.abs(n);
//        });
        /**
         *  使用方法引用优化lambda表达式
         */
        int num = test(-10 , Math::abs);
        System.out.println(num);
    }
    public static int test(int number , FunctionIn2 fun) {
        return fun.calsAbs(number);
    }
}

2.5 通过super关键字执行方法引用

public class MethodDemo3 extends MethodDemo2 {
    public static void main(String[] args) {
        new MethodDemo3().show();
    }
    @Override
    public void sayHello() {
        System.out.println("你好啊!我是Demo3");
    }
    public void test(FunctionIn3 fun) {
        fun.greet();
    }
    public void show() {
//        test(() -> {
//            MethodDemo2 methodDemo2 = new MethodDemo2();
//            methodDemo2.sayHello();
//        });
        /**
         *  使用方法引用优化lambda表达式
         */
        test(super::sayHello);
    }
}

2.6 通过this关键字执行方法引用

public class MethodDemo4 {
    public static void main(String[] args) {
        new MethodDemo4().soHappy();
    }
    public void buyHouse() {
        System.out.println("买大别墅,靠大海!");
    }
    public void marry(FunctionIn4 fun) {
        fun.buy();
    }
    public void soHappy() {
//        marry(() -> {
//            this.buyHouse();
//        });
        /*
          使用方法引用优化lambda表达式
         */
        marry(this::buyHouse);
    }
}

2.7 构造器引用(构造方法引用)

public class MethodDemo5 {
    public static void main(String[] args) {
        printName("飞哥" , (name) -> {
            return new Person(name) ;
        });
        //使用构造器引用优化lambda表达式
        printName("羽羽" , Person::new);
    }
    public static void printName(String name , FunctionIn5 fun) {
        Person person = fun.creatPerson(name);
        System.out.println(person.getName());

    }
}

2.8 数组引用

public class MethodDemo6 {
    public static void main(String[] args) {
        int[] arr1 = test(5 , (n) -> {
            return new int[n] ;
        } );
        System.out.println(arr1.length);
        int[] arr2 = test(6, int[]::new);
        System.out.println(arr2.length);
        System.out.println(Arrays.toString(arr2));
    }
    public static int[] test(int length , FunctionIn6 fun) {
        return fun.buildArr(length);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值