Stream流

本文详细介绍了Java 8中的Stream流和常用函数式接口,包括Predicate和Function接口的使用,如test、and、or、negate方法,以及apply和andThen方法。文章讲解了Stream流的概念,传统集合遍历的弊端,以及Stream流的延迟执行、常用方法如filter、count、limit、skip、map和forEach。此外,还涵盖了流的并发操作和转换为集合或数组的方法。
摘要由CSDN通过智能技术生成

主要内容

  • 常用函数式接口
  • Stream流

学习目标

  • 能够使用Function<T, R>函数式接口
  • 能够使用Predicate函数式接口
  • 能够理解流与集合相比的优点
  • 能够理解流的延迟执行特点
  • 能够通过集合或数组获取流
  • 能够掌握常用的流操作
  • 能够使用流进行并发操作
  • 能够将流中的内容收集(转换为)到集合中
  • 能够将流中的内容收集(转换为)到数组中

1、常用函数式接口

1.1 Predicate接口:测试参数真假,用来条件判断,还有与或非连接

有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate<T>接口。

1.1.1 抽象方法:test,测试条件,返回真假

Predicate接口中包含一个抽象方法:boolean test(T t)。用于一个条件判断的场景:

import java.util.function.Predicate;

public class Demo15PredicateTest {
   
    private static void method(Predicate<String> predicate) {
   
        boolean veryLong = predicate.test("HelloWorld");
        System.out.println("字符串很长吗:" + veryLong);
    }

    public static void main(String[] args) {
   
        method(s -> s.length() > 5);
    }
}

条件判断的标准是传入的Lambda表达式逻辑,只要字符串长度大于5则认为很长。

1.1.2 默认方法:and,并且,判断两个条件是否同时成立&&(了解)

既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个Predicate条件使用“与”逻辑连接起来实现“并且”的效果时,可以使用default方法and。其JDK源码为:

default Predicate<T> and(Predicate<? super T> other) {
   
    Objects.requireNonNull(other);
    return (t) -> this.test(t) && other.test(t);//对于参数来说要求两个条件同时满足
}

如果要判断一个字符串既要包含大写“H”,又要包含大写“W”,那么:

import java.util.function.Predicate;

public class Demo16PredicateAnd {
   
    private static void method(Predicate<String> one, Predicate<String> two) {
   
        boolean isValid = one.and(two).test("Helloworld");
        System.out.println("字符串符合要求吗:" + isValid);
    }

    public static void main(String[] args) {
   
        method(s -> s.contains("H"), s -> s.contains("W"));
    }
}

1.1.3默认方法:or,或者,判断两个条件是否有一个或者两个成立||

and的“与”类似,默认方法or实现逻辑关系中的“”。JDK源码为:

default Predicate<T> or(Predicate<? super T> other) {
   
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}

如果希望实现逻辑“字符串包含大写H或者包含大写W”,那么代码只需要将“and”修改为“or”名称即可,其他都不变:

import java.util.function.Predicate;

public class Demo16PredicateAnd {
   
    private static void method(Predicate<String> one, Predicate<String> two) {
   
        boolean isValid = one.or(two).test("Helloworld");
        System.out.println("字符串符合要求吗:" + isValid);
    }

    public static void main(String[] args) {
   
        method(s -> s.contains("H"), s -> s.contains("W"));
    }
}

1.1.4 默认方法:negate,取反,得到判断条件相反的结果!

“与”、“或”已经了解了,剩下的“非”(取反)也会简单。默认方法negate的JDK源代码为:

default Predicate<T> negate() {
   
    return (t) -> !this.test(t);
}

从实现中很容易看出,它是执行了test方法之后,对结果boolean值进行“!”取反而已。一定要在test方法调用之前调用negate方法,正如andor方法一样:

import java.util.function.Predicate;

public class Demo17PredicateNegate {
   
    private static void method(Predicate<String> predicate) {
   
        boolean veryLong = predicate.negate().test("HelloWorld");
        System.out.println("字符串很长吗:" + veryLong);
    }

    public static void main(String[] args) {
   
      	method(s -> s.length() < 5);
    }
}

1.1.5 练习:集合信息筛选

  • 题目

数组当中有多条“姓名+性别”的信息如下,请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,需要同时满足两个条件:

  1. 必须为女生;
  2. 姓名为4个字。
public class DemoPredicate {
   
    public static void main(String[] args) {
   //使用元素来判断两个条件是否同时成立
      	String[] array = {
    "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };
    }
}
  • 解答
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class DemoPredicate {
   
    public static void main(String[] args) {
   
         String[] array = {
    "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };
        //请通过Predicate接口的拼装将符合要求的字符串元素筛选到集合ArrayList中,需要同时满足两个条件:
        //1. 必须为女生;
        //2. 姓名为4个字。

        m((s)->{
   return s.split(",")[1].contains("女"); }, (s)->{
   return s.split(",")[0].length()==4;}, array);
    }

    public static void m(Predicate<String> p,Predicate<String> p2,String[] arr){
   
        ArrayList<String> al = new ArrayList();

        for (String s : arr) {
   
            if (p.and(p2).test(s)){
   
                al.add(s);
            }
        }

        System.out.println(al);

    }
}

1.2 Function接口:函数应用参数得到返回值,也有并且然后连接

java.util.function.Function<T,R>转换接口,用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。有进有出,所以称为“函数Function”。

1.2.1 抽象方法:apply,应用,根据参数得到方法结果,即把什么东西变成什么东西

Function接口中最主要的抽象方法为:R apply(T t),根据类型T的参数获取类型R的结果。使用的场景例如:将String类型转换为Integer类型。//把T变成字符串类型,把R变成整数类型,就知道这个方法把字符串变成整数

package day13;
import java.util.function.Function;
public class Test03 {
   
    public static void main(String[] args) {
   
        //Function接口中最主要的抽象方法为:R apply(T t),根据类型T的参数获取类型R的结果。
        //使用的场景例如:将String类型转换为Integer类型。
        m((s)->{
   return Integer.parseInt(s);});//lambda表达式写法
        m(Integer::parseInt);//通过方法引用的写法
    }

    public static void m(Function<String,Integer> f)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值