Lambda表达式(Java)

1.简介

Lambda表达式是 jdk1.8 引入的一个新特性,它是函数式编程在Java中的一种体现。也是1.8最值得学习的新特性。

  • Lambda表达式的引入简化了匿名内部类的语法,让代码更加简洁明了。

  • Lambda表达式提供了一种便捷的语法形式,使得函数可以作为参数传递给方法,或者作为返回值返回。

  • Lambda表达式的引入使得Java在并行编程方面具备了更好的支持。

  • lambda表达式本质来讲,是一个匿名函数(匿名方法)。(匿名方法:方法名没有名字)

  • Lambda表达式只能作用于函数式接口有且只有一个抽象方法的接口

2.lambda基础语法

(1)语法与解析

语法:

 (parameters)-> expression      (parameters:参数)

或者      (parameters)-> { statements; }       (statements:语句)

解析:

1.   -> (箭头)将参数与Lambda主体分隔开来。

参数部分:

1.参数可以是任意合法的Java参数列表可以为空或包含一个或多个参数

2.参数列表的类型名可以省略。 不能出现有些省略了,有些没有省略的情况。

3.如果参数列表中,参数的数量有且只有一个,则小括号可以省略。

Lambda主体:

1.Lambda主体可以是一个表达式,表达式外的大括号,可加可不加。 没有大括号时,return关键字必须省略。

2.也可以是一个代码块。将按照常规的Java语法执行,并且您可能需要使用return语句来返回值。

 (2).语法案例:

1.无参数的lambda表达式:

()-> System.out.println("Hello ,Lambda!");

2.带有参数的lambda表达式

(int m) -> System.out.println(m);  //可以省略类型

(m) -> System.out.println(m);

 m  -> System.out.println(m);//只有一个参数,可以省略小括

(int x, int y) -> System.out.println(x + y);
或者
(x, y) -> System.out.println(x + y);

 3.带有多行代码的lambda表达式:

(x, y) -> {
    int sum = x + y;
    System.out.println("Sum: " + sum);
    return sum;
}

3.Lambda的应用场景

(1)lambda的应用场景

lambda表达式,只能作用于函数式接口。

函数式接口:有且只有一个抽象方法的接口。

(2)案例演示:

创建一些接口:

1.里面的抽象方法 没有形参,也没有返回值

interface NoParameterNoReturn{
    void print();
}

2.一个形参,没有返回值

interface OneParameterNoReturn{
    void print(String info);
}

3.多个形参,没有返回值

interface MuilParameterNoReturn {
    void print(String info,int age);
}

4.没有形参,带返回值

interface NoParameterReturn{
    int calculate();
}

5.一个形参,带返回值

interface OneParameterReturn{
    int calculate(int a);
}

6.多个形参,带返回值

interface MuilParameterReturn {
    int calculate(int a,int b);
}

测试:

1.使用实现类的方式,实现NoParameterNoRetrun接口,打印"java编程真简单"

class  Class1  implements NoParameterNoReturn{  //写一个类实现接口,重写接口里的抽象方法
    @Override
    public void print() {
        System.out.println("java编程真简单");
    }
}
public static void main(String[] args) {
        NoParameterNoReturn class1 = new Class1(); 
        class1.print();//调用类里重写的方法
}

2.使用匿名内部类的方式,实现NoParameterNoRetrun接口,打印"我一定能学会java"

public static void main(String[] args) {
    NoParameterNoReturn nono = new NoParameterNoReturn(){   //匿名内部类
            public void print() {
                System.out.println("我一定能学会java");
            }
        };
        nono.print();//调用匿名内部类的方法
}

3.使用lambda表达式,实现NoParameterNoReturn接口,打印"哈哈哈,我哭了...“

NoParameterNoReturn n1 = ()-> System.out.println("哈哈哈,我哭了...");
        n1.print();

4.使用lambda表达式,实现OneParameterNoReturn接口,打印"'我喜欢'+形参",传入'苹果'

OneParameterNoReturn  oneNoRetrun = info-> System.out.println("我喜欢"+info);//一个参数小括号可以省略
        oneNoRetrun.print("苹果");

5.使用lambda表达式,实现MuilParameterNoReturn接口,打印两个参数拼接的效果,传入"我今年","18"

MuilParameterNoReturn  muilNoReturn = (m,n)-> System.out.println(m+n);
        muilNoReturn.print("我今年",18);

6.使用lambda表达式,实现NoParameterReturn接口,计算两个随机数,区间[25,40]的和"

NoParameterReturn noR1 = ()->{
            int a = (int)(Math.random()*16)+25;
            int b = (int)(Math.random()*16)+25;
            return a+b;
        };
        int r1 = noR1.calculate();
        System.out.println("r1="+r1);

 7.使用lambda表达式,实现OneParameterReturn接口,计算形参的立方,测试传入3

OneParameterReturn oneR2 = x -> x*x*x;
        int r2 = oneR2.calculate(3);
        System.out.println("r2="+r2);

// OneParameterReturn oneR2 = x-> {  
//        int a = x*x*x;
//        return a;
//        };
//        int calculate = oneR2.calculate(3);
//        System.out.println(calculate);

8.使用lambda表达式,实现MuilParameterReturn接口,计算两个形参的立方和,测试传入3和4

MuilParameterReturn mR1 = (x,y) -> x*x*x+y*y*y;
        int r3 = mR1.calculate(3,4);
        System.out.println("r3="+r3);
        //或者
//        MuilParameterReturn mR2 = (x,y)->{
//            int n = x*x*x;
//            int m = y*y*y;
//            int sum = m+n;
//            return sum;
//        };
//        int calculate1 = mR2.calculate(3, 4);
//        System.out.println(calculate1);

 4.变量的捕获

(1)匿名内部类的变量捕获

在Java中,匿名内部类可以捕获外部变量,即在匿名内部类中引用并访问外部作用域的变量这种行为称为变量捕获(Variable Capturing)。

在匿名内部类中,可以捕获以下类型的变量:

  • 实例变量(Instance Variables):如果匿名内部类位于一个实例方法中,它可以捕获并访问该实例的实例变量。

  • 静态变量(Static Variables):匿名内部类可以捕获并访问包含它的类的静态变量。

  • 方法参数(Method Parameters):匿名内部类可以捕获并访问包含它的方法的参数。

  • 本地变量(Local Variables):匿名内部类可以捕获并访问声明为final的本地变量。从Java 8开始,final关键字可以省略,但该变量实际上必须是最终的(即不可修改)。

案例:匿名内部类在一个实例方法中

定义一个接口:不用一定是函数式接口

interface Mytest1{
    void test1();
    void test2();
}

测试:

public class VariableCatch {
    private int a;//实例变量
    private static int b;//静态变量
    static {
        b=2; //在静态代码块里赋值
    }
    public VariableCatch(){
        a=1;
    }
    public void m1(int c){
        int d =4;
        Mytest1 mt = new Mytest1() {
            @Override
            public void test1() {
                //访问外部类的成员变量:外部类名.this.成员变量   或者直接写
                System.out.println("instance variable:  "+a);
                //访问外部类的静态变量:外部类名.静态变量,  或者直接写
                System.out.println("static variable:  "+b);
                //匿名内部类访问的方法形参也只能访问,不能覆盖。
                System.out.println("method parameter:  "+c);
                //匿名内部类访问的局部变量是默认被final修饰的;final修饰的变量只能初始化一次。
                System.out.println("native variable:  "+d);
            }

            @Override
            public void test2() {

            }
        };
        mt.test1();
    }
    public static void main(String[] args) {
        VariableCatch variableCatch = new VariableCatch();
        variableCatch.m1(3);
    }
}

 捕获成功:

修改变量的值出现的结果:

1.在匿名内部类的方法体中修改变量的值  ,编译出错

2.在定义的方法中修改变量,出现编译错误。

     (2) lambda表达式的变量捕获

在Lambda表达式中,同样可以捕获外部作用域的变量。Lambda表达式可以捕获以下类型的变量:

  • 实例变量(Instance Variables):Lambda表达式可以捕获并访问包含它的实例的实例变量。

  • 静态变量(Static Variables):Lambda表达式可以捕获并访问包含它的类的静态变量。

  • 方法参数(Method Parameters):Lambda表达式可以捕获并访问包含它的方法的参数。

  • 本地变量(Local Variables):Lambda表达式可以捕获并访问声明为final的本地变量。从Java 8开始,final关键字可以省略,但该变量实际上必须是最终的(即不可修改)

案例:

public class _01InnerClassDemo {
    private int  a;  //实例变量
    private static int  b;//静态变量

    static{
        b = 2;
    }

    public _01InnerClassDemo() {
        a = 1;
    }
    public void m2(int c){
        int d = 4;
        MyTest mt = () ->{
            //访问外部类的成员变量:外部类名.this.成员变量   或者直接写
            System.out.println("instance variable:  "+a);
            //访问外部类的静态变量:外部类名.静态变量,  或者直接写
            System.out.println("static variable:  "+b);
            //访问的方法形参也只能访问,不能覆盖。
            System.out.println("method parameter:  "+c);
            //访问的局部变量是默认被final修饰的;final修饰的变量只能初始化一次。
            System.out.println("native variable:  "+d);
        };
        mt.test1();
    }

    public static void main(String[] args) {
        //测试:创建外部类对象
        _01InnerClassDemo c1 = new _01InnerClassDemo();
        c1.m2(3);
    }
}
interface MyTest{
    void test1();
}

同上面一样,变量也不可修改。

5.Lambda表达式在集合中的应用

(1)集合的排序,使用比较器的时候

public static void main(String[] args)  {
        List<String> list = new ArrayList<>();
        list.add("abdgc");
        list.add("ab");
        list.add("abdgcghsuhcd");
        list.add("abdsugc");
        list.add("abdc");
        //按照字符串的长度降序排序
        list.sort((l1,l2)->l2.length()-l1.length());
        System.out.println(list);
    }

(2)forEach迭代元素

   1)list迭代

public static void main(String[] args)  {
        List<String> list = new ArrayList<>();
        list.add("abdgc");
        list.add("ab");
        list.add("abdgcghsuhcd");
        list.add("abdsugc");
        list.add("abdc");
        list.forEach(list1-> System.out.println(list1));
        //或者更简单的
        list.forEach(System.out::println);
    }

2)Set迭代

public static void main(String[] args)  {
        Integer[] arry = new Integer[]{11,25,4,1,15,6,2,3};
        List<Integer> list = Arrays.asList(arry);
        //想要Set集合
        Set<Integer> set = new HashSet<>(list);
        set.forEach(s-> System.out.println(s));
        //或者
        set.forEach(System.out::println);
    }

3)Map迭代

public static void main(String[] args)  {
        Map<String,Integer> map=new HashMap<>();
        map.put("张三",18);
        map.put("李四",19);
        map.put("王五",17);
        map.put("赵六",28);
        //key的迭代
        map.keySet().forEach( key -> System.out.println(key));
        //entrySet的迭代
        map.entrySet().forEach(entry-> System.out.println(entry.getKey()+"="+entry.getValue()));
        //values的迭代
        map.values().forEach(v-> System.out.println(v));
    }

(3)根据条件移除元素

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(18,19,20,19,24);
        List<Integer> nums = new ArrayList<>(list);
        System.out.println(nums);//[18, 19, 20, 19, 24]
        /**
         * removeIf(Predicate filter):  满足过滤条件就会删除
         * 源码解析:
         *     内部逻辑就是一个迭代器遍历集合,根据条件做删除操作
         *     条件就是filter的test方法。
         * Predicate 是一个函数式接口,里面有boolean test(T t)方法,因此我们在使用时就是写一个
         * lambda表达式来实现test方法即可。
         */
        boolean b = nums.removeIf(m -> m.equals(19));
        System.out.println(b);
        System.out.println(nums);//[18, 20, 24]
    }

复习remove方法:

public static void main(String[] args)  {
        List<String> list = Arrays.asList("18","19","20","19","24");
        List<String> nums = new ArrayList<>(list);
        System.out.println(nums);//[18, 19, 20, 19, 24]
//        nums.remove("19");
//        System.out.println(nums);//[18, 20, 19, 24]只能删除一个
        List<String> list1 = new ArrayList<>();
        list1.add("19");
        list1.add("21");
        nums.removeAll(list1);  //可以全部删除
        System.out.println(nums);//[18, 20, 24]
    }

6.Lambda表达式的优缺点

(1)优点:

  1. 简洁性:Lambda表达式提供了一种更简洁、更紧凑的语法,可以减少冗余的代码和样板代码,使代码更易于理解和维护。

  2. 代码可读性:Lambda表达式使得代码更加自解释和易读,可以直接将逻辑集中在一起,提高代码的可读性和可维护性。

  3. 便于并行处理:Lambda表达式与Java 8引入的Stream API结合使用,可以方便地进行集合的并行处理,充分发挥多核处理器的优势,提高代码的执行效率。

  4. 避免匿名内部类的繁琐语法:相比于使用匿名内部类,Lambda表达式的语法更为简洁,减少了冗余的代码,提高了编码效率。

(2)缺点:

  1. 只能用于函数式接口:Lambda表达式只能用于函数式接口(只有一个抽象方法的接口),这限制了它的使用范围。如果需要使用非函数式接口,仍然需要使用传统的方式,如匿名内部类。

  2. 可读性的折衷:尽管Lambda表达式可以提高代码的可读性,但在某些复杂的情况下,Lambda表达式可能变得难以理解和阅读,特别是当表达式变得过于复杂时。

  3. 变量捕获的限制:Lambda表达式对捕获的变量有一些限制。它们只能引用final或实际上的最终变量,这可能对某些情况下的代码编写和调试带来一些困扰。

  4. 学习曲线:对于习惯于传统Java编程风格的开发者来说,Lambda表达式是一项新的概念,需要一定的学习和适应过程。

7.集合的流式编程

(1)Stream编程的简介

如果想要进行集合的流式编程,必须使用集合实例调用其stream方法

Stream是对集合操作的增强,流不是集合的元素,不是一种数据结构,不负责数据的存储的。流更像是 一个迭代器,可以单向的遍历一个集合中的每一个元素,并且不可循环。

(2)为什么要使用集合的流式编程

有些时候,对集合中的元素进行操作的时候,需要使用到其他操作的结果。在这个过程中,集合的流式 编程可以大幅度的简化代码的数量。将数据源中的数据,读取到一个流中,可以对这个流中的数据进行 操作(删除、过滤、映射...)。每次的操作结果也是一个流对象,可以对这个流再进行其他的操作。

(3)使用流式编程的步骤

1. 传统方式,如果对集合中的元素做处理时,可能要书写大量的代码,比如增加,删除,过滤等

 2. 集合的流式编程:是JDK1.8引入的两个重要特性之一。另一个是Lambda表达式

3. 集合的流式编程是对传统方式的一种简化操作

4. 集合的流式编程,分三步:

         --第一步:获取数据源(关联数据源),返回Stream对象

         --第二步:对Stream对象进行各种处理,处理后的结果依然是Stream对象

         --第三步:对Stream对象的最后整合处理。处理后的结果一般情况下不再是Stream对象,可能是一个具体的数字,字符串,或者一个新的集合。

-- 注意:整个过程中,数据源本身并不会发生变化。

1)获取数据源(关联数据源)

将数据源中的数据读取到流中,进行处理。

public static void main(String[] args)  {
        List<String> list = Arrays.asList("18","19","20","19","24");
        // 获取的流对象,是串行的,好比只有一个人去工作
        Stream<String> stream = list.stream();
        //获取的流对象,是并行的,好比有多个人同时工作。效率高
        Stream<String> stringStream = list.parallelStream();
    }

2)最终操作

  (1)最终操作的简介

将流中的数据整合到一起,可以存入一个集合,也可以直接对流中的数据进行遍历、数据统计... ,通过 最终操作,需要掌握如何从流中提取出来我们想要的信息。

注意事项:最终操作,之所以叫最终操作,是因为,在最终操作执行结束后,会关闭这个流,流中的所有数据都会销毁。如果使用一个已经关闭了的流,会出现异常:stream has already been operated upon or closed

 (2)最终操作的方法
1.colllect:搜集方法,可以将流的数据搜集成一个新的集合。

collect方法的参数,是一个Collector接口,而且这个接口并不是一个函数式接口。实现这个接口, 可以自定义收集的规则。但是,绝大部分情况下,不需要自定义,直接使用Collectors工具类提供的方法即可

    (1)搜集成List集合
public static void main(String[] args)  {
        List<String> list = Arrays.asList("18","19","20","19","24");
        // 获取的流对象,是串行的,好比只有一个人去工作
        Stream<String> stream = list.stream();
        //最后操作,会关闭流
        List<String> collect = stream.collect(Collectors.toList());
        System.out.println(collect);//[18, 19, 20, 19, 24]
    }
   (2)搜集成Set集合
public static void main(String[] args)  {
        List<String> list = Arrays.asList("18","19","20","19","24");
        // 获取的流对象,是串行的,好比只有一个人去工作
        Stream<String> stream = list.stream();
        //最后操作,会关闭流,Set集合不允许重复
        Set<String> collect = stream.collect(Collectors.toSet());
        System.out.println(collect);//[24, 18, 19, 20]
    }
      (3) 搜集成Map集合
 public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(12,23,5,41,36,20);
        Stream<Integer> stream = list.stream();
        Map<String, Integer> collect = stream.collect(Collectors.toMap(e -> "" + e, e -> e));
        System.out.println(collect);//{23=23, 12=12, 36=36, 5=5, 41=41, 20=20}
    }
2.reduce:将流中的数据按照一定的规则聚合起来。(比如计算数据源的元素之和)
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Stream<Integer> stream = list.stream();
        //计算数据源的元素之和  方法参数也是lambda表达式: 对应的抽象方法  R apply(T t, U u);
        //返回的类型:Optional,需要调用它的get方法,获取里面的数据
        Optional<Integer> reduce = stream.reduce((a, b) -> (a + b));
        Integer integer = reduce.get();
        System.out.println(integer);//15
    }

 对Map的键或值进行归约操作

 public static void main(String[] args)  {
       Map<String,Integer> map = new HashMap<>();
       map.put("xiao",25);
       map.put("xi",20);
       map.put("x",30);
       
        Integer reduce = map.values().stream().reduce(0,(a, b) -> a + b);
        System.out.println(reduce);//75,value的和
        String reduce1 = map.keySet().stream().reduce("", (a, b) -> a + b);
        System.out.println(reduce1);//xixiaox  key的拼接操作
    }
3.count统计流中的元素数量
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Stream<Integer> stream = list.stream();
        long count = stream.count();
        System.out.println(count);//5
    }
4.遍历、迭代流中的数据
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Stream<Integer> stream = list.stream();
        stream.forEach(list1-> System.out.println(list1));
        //或者
        //stream.forEach(System.out::println);
    }
5.max&min获取流中的最大的元素、最小的元素。
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Stream<Integer> stream = list.stream();
        /**
         * max方法:根据规则得到的最后一个元素(即都取最后一个元素)
         */
        //升序排序
//        Integer max = stream.max((c1, c2) -> c1 - c2).get();
//        System.out.println("max:"+max);//5
        //降序排序
//        Integer max1 = stream.max((c1, c2) -> c2-c1).get();
//        System.out.println("max1:"+max1);//1

        /**
         * min方法:根据规则得到的第一个元素(即都取第一个元素)
         */
        //升序排序
//        Integer integer = stream.min((c1, c2) -> c1 - c2).get();
//        System.out.println(integer);//1
        //降序排序
        Integer integer = stream.min((c1, c2) -> c2 - c1).get();
        System.out.println(integer);//5
    }
6.Matching

allMatch: 只有当流中所有的元素,都匹配指定的规则,才会返回 true

anyMatch: 只要流中有任意的数据,满足指定的规则,都会返回 true

noneMatch: 只有当流中的所有的元素,都不满足指定的规则,才会返回true

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        boolean b = list.stream().allMatch(e -> e > 0);//所有元素都大于0
        System.out.println(b);//true
        boolean b1 = list.stream().anyMatch(e -> e > 4);//任意一个满足指定的规则
        System.out.println(b1);//true
        boolean b2 = list.stream().noneMatch(e -> e > 5);
        System.out.println(b2);//true  即元素中没有大于5的,都不满足,则返回true
    }
7.find

findFirst: 从流中获取一个元素(一般情况下,是获取的开头的元素)

findAny: 从流中获取一个元素(一般情况下,是获取的开头的元素)

这两个方法,绝大部分情况下,是完全相同的,但是在多线程的环境下, findAny和find返回的结果可能不一样。

针对于串行的流,获取的都是第一个元素

针对于并行的流,获取的元素应该不同

演示:

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        //串行的流
        Integer integer = list.stream().findFirst().get();
        System.out.println(integer);//1
        Integer integer1 = list.stream().findAny().get();
        System.out.println(integer1);//1
        //并行的流   获取的元素不同
        Integer integer2 = list.parallelStream().findFirst().get();
        Integer integer3 = list.parallelStream().findAny().get();
        System.out.println(integer2+" "+integer3);//1  3
    }

最终操作,会关闭流,如果一个流被关闭了,再去使用这个流,就出出现异常。

3)中间操作

(1)中间操作的方法
 1. filter:过滤出满足条件的数据
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,2,3,4,6,8,5,4,2,39,7,5);
        /**
         * filter(...)  过滤出来满足条件的数据
         * 比如,想要所有的奇数,并遍历出来
         */
        list.stream().filter(e->e%2!=0).forEach(System.out::println);
    }
2. distinct:去重操作
 public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(1,1,1,2,2,2,3,3,3,4,4,4);
        System.out.println(list);//[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
        //去重操作
        list.stream().distinct().forEach(System.out::println);//1 2 3 4
    }
3. sorted :排序
public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(2,5,7,3,6,4,1,9);
        System.out.println(list);
        //默认升序
        list.stream().sorted().forEach(System.out::println);
        //降序排序
        list.stream().sorted((c1,c2)->c2-c1).forEach(System.out::println);
    }
4. limit & skip

limit:截取前几个元素。

skip:跳过前几个元素。

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(2,5,7,3,6,4,1,9);
        System.out.println(list);
        //获得前两个元素
        list.stream().limit(2).forEach(System.out::println);
        //跳过前三个元素,遍历后面的元素
        list.stream().skip(3).forEach(System.out::println);
    }
5.map &mapToInt

map(.....) :将元素映射值另外一种类型

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(2,5,7,3,6,4,1,9);
        List<String> collect = list.stream().map(e -> "" + e).collect(Collectors.toList());
        System.out.println(collect);
    }

mapToInt(.....) : 将元素映射成intStream

mapToLong(.....):将元素映射成LongStream

mapToDouble(.....):将元素映射成DoubleStream

public static void main(String[] args)  {
        List<Integer> list = Arrays.asList(2,5,7,3,6,4,1,9);
        //求元素的总和
        int sum = list.stream().mapToInt(e -> e).sum();
        System.out.println(sum);
        Integer integer = list.stream().reduce((a, b) -> (a + b)).get();
        System.out.println(integer);
    }
6.flatMap:扁平式映射 

一般传入一个lambda表达式:e->e.stream()

一般针对的都是集合元素仍然是一个集合。

普通的集合 [1,2,3,4,5]

集合元素是集合的: [[1,2],[1,3,4],[2,4,5]]

扁平式映射:就是将元素是集合的这种特殊集合,转成普通的集合

如 将 右边的集合 [[1,2,10],[1,3,4],[2,4,5]] 转成后面的形式: [1,2,10,1,3,4,2,4,5]

public static void main(String[] args)  {
        List<List<Integer>>  nums = new ArrayList<>();
        nums.add(Arrays.asList(1,2,3));
        nums.add(Arrays.asList(10,12,23));
        nums.add(Arrays.asList(11,22,33));
        List<Integer> collect = nums.stream().flatMap(e -> e.stream()).collect(Collectors.toList());
        System.out.println(collect);//[1, 2, 3, 10, 12, 23, 11, 22, 33]
    }
7.Collectors工具类里的方法:
1.joining()           : 将流中的数据拼接成一个字符串,注意:只能操作流中是String的数据
public static void main(String[] args)  {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        String collect = list.stream().collect(Collectors.joining());
        System.out.println(collect);//abcd
    }
2.summingInt()        : 将流中的数据,映射成  int 类型的数据,并求和
 public static void main(String[] args)  {
       List<Integer> nums = Arrays.asList(1,2,3,6,5,4);
        Integer collect = nums.stream().collect(Collectors.summingInt(e -> e));
        System.out.println(collect);
    }
3.averagingInt()      : 将流中的数据,映射成  int 类型的数据,并求平均值
 public static void main(String[] args)  {
       List<Integer> nums = Arrays.asList(1,2,3,6,5,4);
        Double collect = nums.stream().collect(Collectors.averagingInt(e -> e));
        System.out.println(collect);
    }


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值