jdk1.8新特性(lambda)

一、条件:

必须有接口,有且仅有一个抽象方法:函数式接口

@FunctionalInterface:标记是否为函数式接口

二、接口类型

1.comsumer接口(消费接口)对应的方法是accept

void accept( T);有参无返回值

Consumer<String> consumer = s-> System.out.println(s);
consumer.accept("传入消费的数据");

eg:forEach(s-> System.out.println(s))

2.Supplier接口(生产接口)对应的方法是get

T get();无参有返回值

3.Function接口

有参与返回值

Arrays.stream(new int[]{1,3,4,5}).map(s->s+1).forEach(s-> System.out.println(s));

其中map就用到了function接口,map为映射

三、stream流的操作

1.基本操作
public class Stream01 {
    public static void main(String[] args) {
        //对下面数组求和 外部迭代
        int []arr = new int[]{1,2,3};
        int sum = 0;
        for (int i : arr) {
            sum+=i;
        }
        System.out.println("普通方法求得数组的和为:"+sum);

        //stream流操作 内部迭代
        int sum1 = IntStream.of(arr).sum();
        System.out.println("stream流表达式求得数组的和为:"+sum1);
    }
}
2.中间操作,终止操作,惰性求值
public class Lambda {

    public static void main (String[]args){
        //对下面数组求和
        int[] arr = new int[]{1, 2, 3};
        //stream流操作
        int sum = IntStream.of(arr).map(i -> i * 2).sum();
        System.out.println("stream流表达式求得数组的和为:" + sum);
        //惰性求值,没有对流执行终止操作,所以sum方法没有执行,这就叫惰性求值
        IntStream intStream = IntStream.of(arr).map(Lambda::sum);
        System.out.println("因为惰性求值,没有执行....");
        System.out.println("-----------------------------------------");
        System.out.println("当执行了终止操作后就会执行,惰性求值的方法才会执行");
        intStream.sum();

    }
    public static int sum ( int i){
        System.out.println("对传入的i值加5处理");
        return i + 5;
    }
    
}

结果:
stream流表达式求得数组的和为:12
因为惰性求值,没有执行....
-----------------------------------------
当执行了终止操作后就会执行,惰性求值的方法才会执行
对传入的i值加5处理
对传入的i值加5处理
对传入的i值加5处理
2.1、filter:需要传入一个Preedicate函数式接口的匿名对象
 String name  = "我aa 爱aaa 中aaaa 国aaaaa";
 Stream.of(name.split(" ")).map(s->s.length()).filter(i->i>4).forEach(System.out::println);
2.2、flatMap:需要传入一个Function函数式接口的匿名对象

实用于:A元素下面有一个集合B元素,去获得所有A元素中B元素集合的流

public class Stream04 {
    public static void main(String[] args) {
        List<Student> stuList = new ArrayList<>();
        stuList.add(new Student(1));
        stuList.add(new Student(2));
        //遍历获得student元素 并获得student元素中的list集合 并转换为流形式
      stuList.stream().flatMap(student->student.list.stream()).forEach(System.out::print);
    }
}
class Student{
    List<Integer> list ;
    public Student(int k){
        list = new ArrayList<>();
        list.add(1*k);
        list.add(2*k);
        list.add(3*k);
    }
}

结果:
123246
Process finished with exit code 0
2.3、peek:需要传入一个Consumer函数式接口的匿名对象
public static void main(String[] args) {
    String name  = "我aa 爱aaa 中aaaa 国aaaaa";
    Stream.of(name.split(" ")).peek(System.out::print).forEach(System.out::println);
}
结果:
我aa我aa
爱aaa爱aaa
中aaaa中aaaa
国aaaaa国aaaaa

2.4、limit:限制
public class Stream06 {
    public static void main(String[] args) {
        //随机无限流 产生整数 然后过滤器只取大于100的 用limit限制取10个
       new Random().ints().filter(i->i>100).limit(10).forEach(System.out::println);
    }
}
2.5、去重排序
public static void main(String[] args) {
    // 对数组流,先过滤重复,在排序
   Arrays.asList(3, 1, 2, 1).stream().distinct().sorted().forEach(System.out::println);
}
3、其他:
3.1、orEachOrder:保证在并行流操作时不混乱
public static void main(String[] args) {
    // 用了parallelStream 相当于起了线程池 不同线程输出会混乱
Arrays.asList(3, 1, 2, 1).parallelStream().forEach(i-> System.out.println(Thread.currentThread()+":"+i));
    System.out.println("--------------------------------------------");
    //用forEachOrdered可以保证顺序不乱
    Arrays.asList(3, 1, 2, 1).parallelStream().forEachOrdered(i-> System.out.println(Thread.currentThread()+":"+i));
}
3.2、collect

把流收集为其他类型,比如list、set等

public static void main(String[] args) {
    //将数组元素收集为list集合 不能用new int 因为流没有子类基本数据类型,需要装箱操作
List<Integer> list = Arrays.stream(new Integer[]{1, 2,3}).collect(Collectors.toList());
 System.out.println(list);
}
3.3、reduce
public static void main(String[] args) {
    //用*号拼接
    Optional<String> reduce = Stream.of("a-b-c-d".split("-")).reduce((str1, str2) -> str1 + "*" + str2);
    System.out.println(reduce.get());
    //可以给一个初始值"" 然后再初始值基础上再+
    String reduce1 = Stream.of("a-b-c-d".split("-")).reduce("", (str1, str2) -> str1 + "*" + str2);
    System.out.println(reduce1);
    //比如要计算劈开后的总长度  先获取长度的流 再在0的基础上相加
    Integer reduce2 = Stream.of("a-b-c-d".split("-")).map(str -> str.length()).reduce(0, (i, j) -> i + j);
    System.out.println(reduce2);
}
3.4、min、max、count
//max需要自定义比较策略  这里时按长度的策略比较 min类似
Optional<String> max = Stream.of("aa-bbb-ccc-dddd".split("-")).max((str, str2) -> str.length() - str2.length());
System.out.println(max.get());
//count返回流的长度
long count = Stream.of("aa-bbb-ccc-dddd-ee".split("-")).count();
System.out.println(count);

上面介绍的都是非短路操作,意思遇到这些方法也会把所有的流遍历完。

3.5、短路操作:遇到下面的方法就不会在继续遍历流了
//findFirst:找到第一个就中断无限流
OptionalInt first = new Random().ints().findFirst();
System.out.println(first.getAsInt());

anyMatch表示,判断的条件里,任意一个元素成功,就短路(不在继续遍历流),返回true
allMatch表示,判断条件里的元素,所有的都是,返回true,遇到一个false就短路
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true,有一个匹配上就短路返回false
5>并行流:多线程

1>普通流情况下 一个一个打印,下面使用并行流(多线程):

2>并行流,串行流同时使用,以后面的为准:

public class Stream12 {
    public static void main(String[] args) {
        //串行parallel 并行sequential同时使用 以后面为准 所以下面是串行
        IntStream.range(1,100).parallel().sequential().peek(Stream12::print).count();
    }
    public static void print(int i){
        System.out.println(i);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值