lambda 表达式和 stream流

文章目录

    • lambda 表达式和 stream流
      • lambda表达式
        • 一、lambda表达式简介:
        • 二、Lambda表达式对接口的要求
          • 1、函数式接口
          • 2、@functionalInterface
          • 3、Lambds语法
        • 三、函数引用
          • 1、无参无返回值
          • 2、有输入值无输出例:Consumer 消费者接口。
          • 3、无参有返回值 例:Supplier接口
          • 4、有参有返回值【重要】
            • 1Predicate判断接口
            • 4.2Function转换接口实现
      • Stream流
        • Stream概述:
        • Stream流获取
        • Stream方法
        • 方法案例:

lambda 表达式和 stream流

lambda表达式

一、lambda表达式简介:

java 1.8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中。 使用lambda表达式可以让代码更简洁。

Lambda表达式的使用场景:用以简化接口实现。

关于接口实现,可以有很多方式来实现。例如:设计接口的实现类、使用匿名内部类。Lambda比这两种都简单。

public class Demo1 {
    public static void main(String[] args) {
        Test test = () -> {
            System.out.println("test");
        };
        test.test();
    }
    interface Test{
        public void test();
    }
}
二、Lambda表达式对接口的要求

lambda表达式只是一个匿名方法,当接口中的方法过多或过少的时候1,lambda表达式都是不适用的。

lambda表达式,只能实现函数式接口。

1、函数式接口

​ 定义:如果一个接口中,要求实现类必须实现的抽象方法,有且只有一个,这样的接口,就是函数式接口口。

interface Test{
        public void test();
    }
2、@functionalInterface

​ 这是一个注解,用在接口之前,判断这个接口是否是一个函数是接口。类似于@override

3、Lambds语法

​ 写Lambda表达式的时候,只需要关心参数列表和方法体。

​ (parameters)-> expression 或 (parameters) -> {statements;} 注:如果方法的参数列表中的参数数量 有且只有⼀个,此时,参数列表的小括号是可以省略不写的。

三、函数引用

函数引用:引用⼀个已经存在的方法,使其替代lambda表达式完成接口的实现

1、无参无返回值

接口设计:

@FunctionalInterface
interface A {
	void test();
}

方法设计:

public static void testLambda(A a) {
        a.test();
    }

方法实现:

public static void main(String[] args) {
        testLambda(() -> {
            System.out.println("Lambda 表达式初体验");
        });
    }

常用函数接口:

2、有输入值无输出例:Consumer 消费者接口。

接口设计:

@FunctionalInterface
interface Consumer<T> {
    void accept(T t);
}

void accept(T t):对给定的参数执行此操作。

方法设计:

public static void testLambda(String str, Consumer<String> handle) {
        handle.accept(str);
    }

方法实现:

public static void main(String[] args) {
        testLambda("lambda要处理的字符串", (s) -> {
            System.out.println(Arrays.toString(s.toCharArray()));
        });


    }
3、无参有返回值 例:Supplier接口

接口设计:

@FunctionalInterface
interface Supplier<T> {
    /**
     * 无参数有返回值方法,泛型约束的是接口对应的返回值数据类型,要求
     * 按照泛型约束返回对应的数据内容
     */
    T get();
}

方法设计:

public static String testLambda(Supplier<String> s) {
        return s.get();
    }
//返回一个String类型的

方法实现:

 public static void main(String[] args) {
        String s1 = testLambda(() -> {
            return "这里也是一个字符串";
        });
        System.out.println(s1);
    }
4、有参有返回值【重要】
  1. 1Predicate判断接口

Predicate:常用的四个方法:

​ boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值

​ default Predicate negate():返回一个逻辑的否定,对应逻辑非
​ default Predicate and(Prduicate other):返回一个组合判断,对应短路与
​ default Predicate or(Predicate other):返回一个组合判断,对应短路或

接口设计:

// 过滤器接口,判断器接口,条件接口
@FunctionalInterface
interface Predicate<T> {
    boolean test(T t);
}

方法设计:

 public static Person[] filterPersonArrayUsingPredicate(Person[] array, Predicate<Person> filter) {
        Person[] temp = new Person[array.length];

        int count = 0;
        for (int i = 0; i < array.length; i++) {
            if (filter.test(array[i])) {
                temp[count++] = array[i];
            }
        }

        return temp;
    }

方法实现:

public static void main(String[] args) {
    Person[] array = new Person[5];

    for (int i = 0; i < array.length; i++) {
        int age = (int) (Math.random() * 50);
        array[i] = new Person(i + 1, "张三", age, false);
    }
    Person[] temp = filterPersonArrayUsingPredicate(array, p -> p.getAge() > 10);

    for (Person person : temp) {
        System.out.println(person);
    }

}

输出结果:

Person{id=2, name='张三', age=28, gender=false}
Person{id=4, name='张三', age=42, gender=false}
Person{id=5, name='张三', age=29, gender=false}
null
null
4.2Function转换接口实现

​ Function:常用的两个方法。

​ R apply(T t);将此函数应用于给定的函数。

接口设计:

@FunctionalInterface
interface Function<T,R>{
    R apply(T t);
}

方法设计;

 public static int testLambda(String str, Function<String, Integer> fun) 	{
        return fun.apply(str);
    }

方法实现

public static void main(String[] args) {
        String str = "开封有个包青天";
        int i = testLambda(str, s -> s.length());
        System.out.println(i);
    }

输出结果:

7

Stream流

Stream概述:

​ java8 api添加了一个新的抽象成为Stream流,可以让编程者用一种声明的方式处理数据。

​ Stream极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

数据源:可以是集合,数组,I/O channel,生产器generator等。

Stream流获取

​ 根据集合来获取:

​ 根据Collection获取流:

​ Collection接口中有一个stream()方法,可以获取流

  default Stream<E> stream()

​ 1.根据List获取流

List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();

​ 2.根据Set获取流

Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();

​ 3.根据Map获取流

​ 3.1根据Map集合的键来获取流

Map<Integer,String> map = new HashMap<>();
Set<Integer> map1 = map.keySet();
Stream<Integer> stream3 = map1.stream();

​ 3.2根据Map集合的值获取流

Map<Integer,String> map = new HashMap<>();
Collection<String> map2 = map.values();
Stream<String> stream4 = map2.stream();

​ 3.3根据Map集合的键值对对象获取流

 Map<Integer,String> map = new HashMap<>();
 Set<Map.Entry<Integer, String>> map3 = map.entrySet();
 Stream<Map.Entry<Integer, String>> stream5 = map3.stream();

​ 4.根据数组获取

 String[] arr = {"张颜宇","张三","李四","赵五","刘六","王七"};
 Stream<String> stream6 = Stream.of(arr);
Stream方法

Stream 处理数据的【中间方法】:skip、limit、sorted、sorted、filter、distinct、map

Stream 处理数据的【最终方法/终止方法】:

​ 终止方法,Stream 流自动关闭。对应 Stream 占用的资源空间会被 JVM 收回。count、forEach、collect、toArray()

方法案例:

Stream提供了新的方法’forEach’来迭代流中的每个数据。例如随机输出10个随机数:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

map:方法用于映射每个元素对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();

limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

		Collectors.toList() 目标存储集合类型为 List 集合
		Collectors.toSet()  目标存储集合类型为 Set 集合

你可能感兴趣的:(java,开发语言)