Java补充(Java8新特性)(和IO都很核心)

一、Lambda表达式

1.1、为什么使用Lambda表达式 Lambda表达式起步案例

下面源码注释是传统写法,代码是简写表达式写法

import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.function.Consumer; /** 学什么?*   1、Lambda表达式*   2、Stream API*   3、Optional类 NullPointerException* 目前存在的问题?*   方法不能作为参数传递* 如何解决这个问题?*   行为参数化* */public class MyTest02 {    public static void main(String[] args) {        //匿名内部类        /*Thread th1 = new Thread(new Runnable() {            @Override            public void run() {                System.out.println("hello Java8");            }        });        th1.start();*/        Thread th1 = new Thread(() -> {            System.out.println("hello Java8");        });        th1.start();         ArrayList list = new ArrayList();        list.add("111111");        list.add("11");        list.add("11222");        list.add("1");         /*Collections.sort(list, new Comparator() {            @Override            public int compare(String o1, String o2) {                //return o1.length() - o2.length();                return Integer.compare(o1.length(), o2.length());            }        });*/        // -> 后省略了大括号和return 还有o1,o2的String        Collections.sort(list, (o1,o2) -> Integer.compare(o1.length(), o2.length()));        System.out.println(list);         /*list.forEach(new Consumer() {            @Override            public void accept(String s) {//s -- 每次被遍历到的元素                System.out.println(s);            }        }); 下面是简写后的*/        list.forEach(s -> System.out.println(s));        list.forEach(System.out::println);    }}

1.2、Lambda表达式写法

Lambda表达式是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格。使Java的语言表达能力得到了提升。

语法:

Lambda表达式操作符或箭头操作符:->

左侧:指定了Lambda表达式需要的参数列表(其实就是接口中的抽象方法的形参列表)

右侧:指定了Lambda体,是抽象方法的实现逻辑,也即Lambda表达式要执行的功能(其实就是重写的抽象方法的方法体)。

先把匿名内部类的对象找出来,再看方法参数和方法体

即源码

package day33; import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.function.Consumer; /** 学什么?*   1、Lambda表达式*   2、Stream API*   3、Optional类 NullPointerException* 目前存在的问题?*   方法不能作为参数传递* 如何解决这个问题?*   行为参数化* Lambda表达式*   -> Lambda操作符或箭头操作符*   左侧:方法的参数列表*   右侧:方法的方法体*   方法:重写的方法* Lambda表达式简写/进阶写法*   1、如果参数列表没有参数,要写成()*   2、如果参数列表有参数*     参数个数>=2 (数据类型1 参数名1,数据类型2 参数名2,数据类型3 参数名3)*     参数个数>=2 (参数名1, 参数名2,参数名3) !!!!!*     只有一个参数 (数据类型 参数名)*     只有一个参数 (参数名)*     只有一个参数 参数名 !!!!!*   3、右侧 - 如果方法体有多行代码,必需写{}*   4、右侧 - 如果方法体只有一行代码,不用写{},不用写return,不用写结尾的";" * */public class MyTest02 {    public static void main(String[] args) {        //匿名内部类        /*Thread th1 = new Thread(new Runnable() {            @Override            public void run() {                System.out.println("hello Java8");            }        });        th1.start();*/        Thread th1 = new Thread(() -> {            System.out.println("hello Java8");        });        th1.start();         ArrayList list = new ArrayList();        list.add("111111");        list.add("11");        list.add("11222");        list.add("1");         /*Collections.sort(list, new Comparator() {            @Override            public int compare(String o1, String o2) {                //return o1.length() - o2.length();                return Integer.compare(o1.length(), o2.length());            }        });*/        // -> 后省略了大括号和return 还有o1,o2的String        Collections.sort(list, (o1,o2) -> Integer.compare(o1.length(), o2.length()));        System.out.println(list);         /*list.forEach(new Consumer() {            @Override            public void accept(String s) {//s -- 每次被遍历到的元素                System.out.println(s);            }        }); 下面是简写后的*/        list.forEach(s -> System.out.println(s));        list.forEach(System.out::println);    }}

1.3、函数式接口_@Functional注解

@FunctionalInterface
@Override
作用:编译器帮我们检查标注了该注解的接口是不是函数式接口
      |-- 是 -- 编译通过
      |-- 不是 -- 无法编译通过
      注意:该注解的作用只是检查的作用,可以不写

相关源码显示:

package day33; public class MyTest03 {    public static void aaa(MyInterface a, int m , int n) {        a.test(m,n);    }     public static void main(String[] args) {        /*aaa(new MyInterface() {            @Override            public void test(int a, int b) {                System.out.println(a + ":" + b);            }        },1,2);*/        aaa((a,b) -> System.out.println(a + ":" + b),1,2);    }}
package day33; @FunctionalInterfacepublic interface MyInterface {    void test(int a , int b);    //唯一的一个抽象方法}

———————自己定义的,Java官方也有

1.4、函数式接口_常见函数式接口说明

1.5、复合的Lambda表达式

 比较器复合 和 谓词复合

package day34; import java.util.ArrayList;import java.util.Comparator;import java.util.function.Predicate; //比较器复合public class MyTest02 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();         list.add(new Apple(150,"red"));        list.add(new Apple(210,"red"));        list.add(new Apple(300,"yellow"));        list.add(new Apple(90,"green"));        list.add(new Apple(90,"yellow"));        list.add(new Apple(100,"green"));        list.add(new Apple(123,"red"));         //按照重量降序排序        //list.sort(Comparator.comparing(Apple::getWeight).reversed());        //按照重量降序排序,如果重量相同那就按照颜色的升序排序        /*list.sort(Comparator.                comparing(Apple::getWeight)                .reversed()                .thenComparing(Apple::getColor));*/        //.thenCompareing(Comparator.comparing(Apple::getColor).reversed()));        //list.removeIf(item -> item.getWeight() == 90);        //删除颜色不是红颜色的苹果 Predicate的复合即谓词复合        Predicate redApple = item -> item.getColor().equals("red");        //list.removeIf(redApple.negate());        //去除红颜色并且重量大于150的苹果        list.removeIf(redApple.and(item -> item.getWeight() > 150));        //去除红色并且重量大于150的苹果或绿苹果        list.removeIf(redApple.and(item -> item.getWeight() > 150).or(item -> item.getColor().equals("green")));        list.forEach(System.out::println);    }}

二、方法引用

1、本质:就是Lambda表达式,对Lambda表达式的简写

2、比如类名::方法名,一般带两个冒号的就是

 什么情况下Lambda表达式可以改成方法引用?

1)Lambda表达式的方法体只有一行代码,并且只调用了一个方法

2)除了参数列表和1)中的"一个方法",没有再引入其他的额外的内容

三、Stream_中间操作

3.1、filter 过滤符合条件的

package day34; import java.util.ArrayList; public class MyTest04 {    public static void main(String[] args) {        //filter -- 中间操作        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         //在控制台打印长度大于2的字符串        list.stream()                .filter(item -> item.length() > 2) //--> Stream                .forEach(System.out::println);        System.out.println("--------------------------------");          System.out.println(list);    }}

3.2、distinct 去重

import java.util.ArrayList; public class MyTest04 {    public static void main(String[] args) {        //filter -- 中间操作        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         //在控制台打印长度大于2的字符串        /*list.stream()                .filter(item -> item.length() > 2) //--> Stream                .forEach(System.out::println);        System.out.println("--------------------------------");*/        //去除重复        list.stream()                .distinct() //根据元素的equals和hashCode方法判断是否重复                .forEach(System.out::println);        System.out.println("--------------------------------");         ArrayList list1 = new ArrayList<>();         list1.add(new Apple(150,"red"));        list1.add(new Apple(210,"red"));        list1.add(new Apple(300,"yellow"));        list1.add(new Apple(90,"green"));        list1.add(new Apple(90,"yellow"));        list1.add(new Apple(90,"yellow"));        list1.add(new Apple(100,"green"));        list1.add(new Apple(123,"red"));                list1.stream()                .distinct()                .forEach(System.out::println);             }}

3.3、limit 截断流 使其元素不超过给定数量

System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        list1.stream()                .limit(3)                .forEach(System.out::println);

3.4、skip 跳过元素,返回一个扔掉了前n个元素的流,若元素不足n个,返回空流

list1.stream()      .skip(3)      .forEach(System.out::println);

3.5、map 映射 将流中的每个元素进行转换

3.5.1、传统做法

package day34; import java.util.ArrayList;import java.util.LinkedHashSet; public class MyTest05 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         //map - 映射 - 将流中的每个元素进行转换        //获取list中每个字符串的长度并在控制台打印        list.stream()//String                .map(s -> s.length())//长度                .forEach(System.out::println);        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        //获取list中每个字符串的长度并在控制台打印,去除重复的长度        list.stream()                .map(String::length)                .distinct()                .forEach(System.out::println);        System.out.println(" setLength = new LinkedHashSet<>();        for (String s : list) {            setLength.add(s.length());        }        for (Integer len : setLength) {            System.out.println(len);        }    }}

3.5.2、flatMap 把多个流合并成一个流

System.out.println("__________________________________________");         list.stream()                .mapToInt(String::length)                .distinct()                .forEach(System.out::println);         ArrayList list1 = new ArrayList<>();        list1.add("Hello");        list1.add("World"); //H e l l o W o r l d         list1.stream() //String                .map(s -> s.split("")) //String --> String[]                .flatMap(arr -> Arrays.stream(arr)) //String[] --> Stream -->Stream合并                .forEach(System.out::println);        /* 传统的 上面的是新的        String[] arr = "hahaha".split("");        System.out.println(Arrays.toString(arr));*/

四、Stream_终端操作

补forEach:没有返回值

4.1、allMatch_anyMatch_noneMatch

package day34; import java.util.ArrayList;  public class MyTest06 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        //list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         boolean flag = list.stream()                .allMatch(s -> s.length() > 2); //判断所有元素是否达到要求        System.out.println(flag);         boolean flag1 = list.stream()                .anyMatch(s -> s.length() > 2); //判断是否有元素是否达到要求        System.out.println(flag1);         boolean flag2 = list.stream()                .noneMatch(s -> s.length() > 2); //判断没有任何元素达到要求        System.out.println(flag2);    }}

4.2、findFirst_findAny

package day34; import java.util.ArrayList;import java.util.Optional; public class MyTest06 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        //list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         boolean flag = list.stream()                .allMatch(s -> s.length() > 2); //判断所有元素是否达到要求        System.out.println(flag);         boolean flag1 = list.stream()                .anyMatch(s -> s.length() > 2); //判断是否有元素是否达到要求        System.out.println(flag1);         boolean flag2 = list.stream()                .noneMatch(s -> s.length() > 2); //判断没有任何元素达到要求        System.out.println(flag2);         Optional first = list.stream().findFirst(); //获取第一个元素        System.out.println(first.get());         Optional any = list.stream().findAny(); //获取任意一个元素        System.out.println(any.get());    }}

4.3、reduce

!!!!!归约!!!!!

之前见到过的终端操作都是返回一个boolean(allMatch之类的)、void(forEach)或Optional对象(findAny)等。使用reduce操作来表达更复杂的查询,此类查询需要将流中所有元素反复结合起来,得到一个值,比如一个Integer.这样的查询可以被归类为归约操作(将流归约成一个值)

package day34; import java.util.Arrays;import java.util.Optional; public class MyTest07 {    public static void main(String[] args) {        Integer[] arr = new Integer[]{1,2,3};        /*Integer sum = Arrays.stream(arr)                .reduce(0, (n1, n2) -> n1 + n2);*/         /*Integer sum = Arrays.stream(arr)                .reduce(0, (n1, n2) -> Integer.sum(n1, n2));*/         Integer sum = Arrays.stream(arr)                .reduce(0, Integer::sum);        System.out.println(sum);        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        Optional sum1 = Arrays.stream(arr)                .reduce(Integer::sum);        System.out.println(sum1.get());                //最大值        /*Integer max = Arrays.stream(arr)                .reduce(arr[0], (n1, n2) -> {                    if (n1 > n2) {                        return n1;                    } else {                        return n2;                    }                });*/       /* Integer max = Arrays.stream(arr)                .reduce(arr[0], (n1, n2) -> n1 > n2 ? n1 : n2);*/        /*Integer max = Arrays.stream(arr)                .reduce(arr[0], (n1, n2) -> Integer.max(n1, n2));*/        Integer max = Arrays.stream(arr)                .reduce(arr[0], Integer::max);        System.out.println("Max = " + max);         Optional max1 = Arrays.stream(arr)                .reduce(Integer::max);//没有起始值的        System.out.println("Max1 = " + max1.get());                //最小值        Integer min = Arrays.stream(arr)                .reduce(arr[0], Integer::min);        System.out.println("Min = " + min);                //最佳实践:包装类判断值是否相同要使用equals判断        Integer i1 = 1000;        Integer i2 = 1000;        System.out.println(i1 == i2);//不行        System.out.println(i1.equals(i2));    }}

 小练习:

怎样用map 和 reduce 方法计算流中元素的数据。

//计算流中的元素个数        //把元素值都变成1,累加起来即为sum        Integer count = Arrays.stream(arr)                .map(item -> 1)                .reduce(0, Integer::sum);        System.out.println(count);

4.4、sorted

package day34; import java.util.ArrayList;import java.util.Comparator; public class MyTest08 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        //list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");                list.stream()                .sorted() //自然排序                .forEach(System.out::println);        System.out.println("==============================================");                /*list.stream()                .sorted((s1, s2) -> Integer.compare(s1.length(), s2.length()))                .forEach(System.out::println);*/        list.stream()                .sorted(Comparator.comparingInt(String::length).reversed().thenComparing(String::compareTo))                .forEach(System.out::println);         System.out.println("-----------------------------------------------");        System.out.println(list.stream().count());     }}

4.5、Stream的终止操作

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值。例如:List、Integer,甚至是void。

流进行了终止操作后,不能再次使用。

package day35; import java.util.ArrayList;import java.util.stream.Stream; public class MyTest01 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         Stream stream = list.stream();        stream.map(item -> 1).forEach(System.out::println);        //流一旦进行了终端操作就不能再重复使用,报错        stream.map(item -> 1).forEach(System.out::println);    }}

4.5.1、匹配与查找

package day35; import java.util.ArrayList;import java.util.Optional;import java.util.stream.Stream; public class MyTest01 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         System.out.println(list.stream().count());         Optional max = list.stream()                //.max((s1, s2) -> s1.compareTo(s2));                .max(String::compareTo);        System.out.println(max.get());    }}

4.6、collect

package day35; import java.util.*;import java.util.stream.Collectors; public class MyTest02 {    public static void main(String[] args) {        ArrayList list = new ArrayList<>();        list.add("Aqaa");        list.add("Bssss");        list.add("Cwww");        list.add("Ddsdd");        list.add("Edadc");         /*ArrayList nums = new ArrayList<>();        list.stream()                .map(String::length)                .forEach(len -> nums.add(len));        System.out.println(nums);*/         List nums = list.stream()                .map(String::length)                .collect(Collectors.toList());//把流当中的元素给搜集到集合里面,并作为元素返回        Set nums1 = list.stream()                .map(String::length)                .collect(Collectors.toSet());//Set方法自动去重,Collectors可省略         TreeSet num2 = new TreeSet<>(nums1);//合并转换        System.out.println(num2);         System.out.println(nums1);        System.out.println("------------------------------------------------");        String s = list.stream()                .map(str -> str.substring(0, 1))                .collect(Collectors.joining("+"));        System.out.println(s);         //例子:搜集所有参与交易的交易员姓名到一个集合中        /*List names = transactions.stream()                .map(Transaction::getTrader)                .map(Trader::getName)                .distinct                .collect(Collectors.toList());        System.out.println(names);*/     }}

posted on 2025-06-26 18:13  ljbguanli  阅读(10)  评论(0)    收藏  举报