Java新特性(jdk8)

第一章-lambda表达式

1.函数式编程思想和Lambda表达式定义格式

1.面向对象思想:

强调的是找对象,帮我们去做事儿

比如:去北京 -> 强调的是怎么去,火车,高铁,飞机,汽车,自行车,腿儿

2.jdk8开始有了一个新的思想:函数式编程思想:

强调的是结果,不强调过程

比如:去北京 -> 只强调去了还是没去

3.Lambda表达式语法:

a.定义格式:

()->{}

b.各部分解释:

() : 重写方法的参数位置

-> : 将参数传递到方法体中

{} : 重写方法的方法体位置

java 复制代码
public class Demo01Lambda {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我执行了");
            }
        }).start();

        System.out.println("===================");

        new Thread(()-> System.out.println("我执行了")).start();
    }
}

2.Lambda表达式使用前提

1.必须是函数式接口做方法参数传递

2.啥叫做函数式接口

有且只有一个抽象方法的接口,用@FunctionalInterface去检测

3.Lambda表达式省略规则

1.Lambda表达式怎么写(涛哥给的新手教程)

a.观察是否是函数式接口做方法参数传递

b.如果是,考虑使用Lambda表达式

c.调用方法,以匿名内部类的形式传递实参

d.从new接口开始到重写方法的方法名结束,选中,删除,别忘记再删除一个右半个大括号

e.在重写方法的参数后面,方法体的大括号前面加上 ->

2.省略规则:

a.重写方法的参数类型可以干掉

b.如果重写方法只有一个参数,所在的小括号可以干掉

c.如果方法体中只有一句话,那么所在的大括号以及分号可以干掉

d.如果方法体中只有一句话并且带return,那么所在的大括号以及分号以及return可以干掉

java 复制代码
public class Person {
    private String name;
    private Integer age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
java 复制代码
public class Demo02Lambda {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("张三",10));
        list.add(new Person("李四",8));
        list.add(new Person("王五",9));

        /*Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });*/

        Collections.sort(list, (Person o1, Person o2)-> {
                return o1.getAge()-o2.getAge();
        });

        System.out.println("============Lambda表达式终极形式================");

        Collections.sort(list, (o1,o2)-> o1.getAge()-o2.getAge());

        System.out.println(list);
    }
}

第二章-函数式接口

1.函数式接口:

有且只有一个抽象方法的接口

2.检测:

@FunctionalInterface

java 复制代码
@FunctionalInterface
public interface USB {
    void open(String s);
    //void close();
}
java 复制代码
public class Test01 {
    public static void main(String[] args) {
        method(new USB() {
            @Override
            public void open(String s) {
                System.out.println(s+"开启了");
            }
        });

        System.out.println("==========Lambda===========");
        method((String s)-> {
                System.out.println(s+"开启了");
        });

        System.out.println("========Lambda最终形式======");

        method(s-> System.out.println(s+"开启了"));
    }
    public static void method(USB usb){
        usb.open("鼠标");
    }
}

1.Supplier

1.Supplier接口

java.util.function.Supplier<T>接口,它意味着"供给"->我们想要什么就给什么

2.方法:

T get() -> 我们想要什么,get方法就可以返回什么

3.需求:

使用Supplier接口作为方法的参数

用Lambda表达式求出int数组中的最大值

4.泛型:

<引用数据类型>-> 规定了我们操作的数据是什么类型

<>中只能写引用数据类型,不能写基本数据类型

java 复制代码
public class Demo01Supplier {
    public static void main(String[] args) {
        method(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int[] arr = {5,2,0,6,3,5,7};
                Arrays.sort(arr);
                return arr[arr.length-1];
            }
        });
        System.out.println("========Lambda表达式======");

        method(()-> {
                int[] arr = {5,2,0,6,3,5,7};
                Arrays.sort(arr);
                return arr[arr.length-1];
        });
    }
    public static void method(Supplier<Integer> supplier){
        Integer max = supplier.get();//让get方法返回一个数组最大值
        System.out.println("max = " + max);
    }
}

2.Consumer

java.util.function.Consumer<T>->消费型接口->操作

方法:

void accept(T t),意为消费一个指定泛型的数据

"消费"就是"操作",至于怎么操作,就看重写accept方法之后,方法体怎么写了

java 复制代码
public class Demo02Consumer {
    public static void main(String[] args) {
        method(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s.length());
            }
        },"abcdefg");

        System.out.println("=====Lambda表达式=====");
        method((String s)->{
                System.out.println(s.length());
        },"abcdefg");

        System.out.println("========Lambda表达式终极写法=======");
        method(s-> System.out.println(s.length()),"abcdefg");

    }

    public static void method(Consumer<String> consumer,String s){
        consumer.accept(s);
    }
}

3.Function

java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据

方法:

R apply(T t)根据类型T参数获取类型R的结果

java 复制代码
public class Demo03Function {
    public static void main(String[] args) {
        method(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer+"";
            }
        },100);

        System.out.println("=======Lamba=======");

        method(integer -> integer+"",200);
    }

    public static void method(Function<Integer,String> function,Integer number){
        String result = function.apply(number);
        System.out.println("result = " + result+1);
    }
}

4.Predicate

java.util.function.Predicate<T>接口。->判断型接口

boolean test(T t)->用于判断的方法,返回值为boolean型

java 复制代码
public class Demo04Predicate {
    public static void main(String[] args) {
        method(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 7;
            }
        }, "abcdefg");

        System.out.println("==============");

        method(s -> s.length()==7,"abcdefg");
    }

    public static void method(Predicate<String> predicate, String s) {
        boolean result = predicate.test(s);
        System.out.println("result = " + result);
    }
}

第三章-Stream流

java 复制代码
public class Demo01Stream {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("张三丰");
        list.add("张大彪");
        list.add("吕不韦");
        list.add("张三");
        list.add("赵姬");
        list.add("张翠山");
        list.add("嫪毐");

        //需求1:筛选出姓张的
       /* ArrayList<String> listZhang = new ArrayList<>();
        for (String s : list) {
            if (s.startsWith("张")){
                listZhang.add(s);
            }
        }
        System.out.println(listZhang);

        System.out.println("=====================");
*/
        //需求2:筛选出三个字的
      /*  ArrayList<String> listThree = new ArrayList<>();
        for (String s : listZhang) {
            if (s.length()==3){
                listThree.add(s);
            }
        }
        System.out.println(listThree);*/

        //需求3:遍历
       /* for (String s : listThree) {
            System.out.println(s);
        }*/

        System.out.println("===========================");

        Stream<String> stream = list.stream();
        stream.filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s -> System.out.println(s));
    }
}

1.Stream的获取

1.针对集合:Collection中的方法

Stream<E> stream();

2.针对于数组:Stream接口中静态方法:

static <T> Stream<T> of(T... values)

java 复制代码
public class Demo02Stream {
    public static void main(String[] args) {
        /*
          针对集合:Collection中的方法
            Stream<E> stream();

         */
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        Stream<String> stream = list.stream();
        System.out.println(stream);

        System.out.println("====================");

        /*
          针对于数组:Stream接口中静态方法:
               static <T> Stream<T> of(T... values)
         */
        Stream<String> stream2 = Stream.of("张三", "李四", "王五");
        System.out.println("stream2 = " + stream2);
    }
}

2.Stream的方法

2.1.Stream中的forEach方法:void forEach(Consumer<? super T> action);

forEach : 逐一处理->遍历

void forEach(Consumer<? super T> action);

注意:forEach方法是一个终结方法,使用完之后,Stream流不能用了

java 复制代码
public class Demo03Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六", "田七", "猪八");
        /*stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        System.out.println("========Lambda表达式==========");

       /* stream.forEach((String s)-> {
                System.out.println(s);
        });*/

        System.out.println("========Lambda表达式终结写法==========");

        stream.forEach(s-> System.out.println(s));
        
    }
}

2.2.Stream中的long count()方法

1.作用:统计元素个数

2.注意:count也是一个终结方法

java 复制代码
public class Demo04Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠", "封神榜传奇", "古希腊神话");
        long count = stream.count();
        System.out.println("count = " + count);
    }
}

2.3.Stream中的Stream<T> filter(Predicate<? super T> predicate)方法

.方法:Stream<T> filter(Predicate<? super T> predicate)方法,返回一个新的Stream流对象

2.作用:根据某个条件进行元素过滤

java 复制代码
public class Demo05Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠", "封神榜传奇", "古希腊神话");
       /* Stream<String> stream1 = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 4;
            }
        });

        stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

       /* stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 4;
            }
        }).forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        System.out.println("========Lambda表达式======");

        stream.filter(s-> s.length() == 4).forEach(s-> System.out.println(s));
    }
}

2.4.Stream<T> limit(long maxSize):获取Stream流对象中的前n个元素,返回一个新的Stream流对象

1.Stream<T> limit(long maxSize):获取Stream流对象中的前n个元素,返回一个新的Stream流对象

java 复制代码
public class Demo06Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠", "封神榜传奇", "古希腊神话");
        stream.limit(3).forEach(s -> System.out.println(s));
    }
}

2.5.Stream<T> skip(long n): 跳过Stream流对象中的前n个元素,返回一个新的Stream流对象

Stream<T> skip(long n): 跳过Stream流对象中的前n个元素,返回一个新的Stream流对象

java 复制代码
public class Demo07Stream {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠", "封神榜传奇", "古希腊神话");
        stream.skip(2).forEach(s -> System.out.println(s));
    }
}

2.6.static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):两个流合成一个流

1.方法:static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):两个流合成一个流

java 复制代码
public class Demo08Stream {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠");
        Stream<String> stream2 = Stream.of("西施", "貂蝉", "杨玉环","王昭君");

        Stream.concat(stream1,stream2).forEach(s -> System.out.println(s));
    }
}

2.7.将Stream流变成集合

从Stream流对象转成集合对象,使用Stream接口方法collect

java 复制代码
public class Demo09Stream {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("飞天小女警", "马丁的早晨", "猫和老鼠");
        List<String> list = stream1.collect(Collectors.toList());
        for (String s : list) {
            System.out.println(s);
        }
    }
}

2.8 Stream流练习

  1. 第一个队伍只要名字为3个字的成员姓名;//filter

  2. 第一个队伍筛选之后只要前3个人;//limit

  3. 第二个队伍只要姓张的成员姓名;//filter

  4. 第二个队伍筛选之后不要前2个人;//skip

  5. 将两个队伍合并为一个队伍;//concat

  6. 打印整个队伍的姓名信息。//foreach

java 复制代码
public class Demo10Stream {
    public static void main(String[] args) {
        ArrayList<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("老子");
        one.add("庄子");
        one.add("孙子");
        one.add("洪七公");

        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("赵丽颖");
        two.add("张二狗");
        two.add("张天爱");
        two.add("张三");

        //将两个集合变成Stream流对象
        Stream<String> oneTeam = one.stream();
        Stream<String> twoTeam = two.stream();

        //Stream<String> teamA = oneTeam.filter(s -> s.length() == 3).limit(3);

        //Stream<String> teamB = twoTeam.filter(s -> s.startsWith("张")).skip(2);

        Stream.concat(oneTeam.filter(s -> s.length() == 3).limit(3),twoTeam.filter(s -> s.startsWith("张")).skip(2)).forEach(s -> System.out.println(s));

    }
}

第四章节-方法引用

1)方法引用的介绍

1.概述:引用方法

2.啥时候用:

a.被引用的方法要写在重写的方法里面

b.被引用的方法从参数上,返回值上要和所在重写方法一致,而且引用的方法最好操作重写方法的参数值

c.干掉重写方法的参数,干掉->,干掉被引用方法的参数,将.改成:

2)方法引用的体验

java 复制代码
public class Demo01Method {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("曼曼", "三上", "金莲", "松下", "有菜", "井上");
        /*
           accept是重写方法:  参数类型为String
                            没有返回值

           想引用println:   println参数类型为String,被引用的方法操作重写方法的参数值
                           没有返回值
         */

        /*stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        stream.forEach(System.out::println);
    }
}

3)对象名--引用成员方法

1.使用对象名引用成员方法

格式:

对象::成员方法名

2.需求:

函数式接口:Supplier

java.util.function.Supplier<T>接口

抽象方法:

T get()。用来获取一个泛型参数指定类型的对象数据。

Supplier接口使用什么泛型,就可以使用get方法获取一个什么类型的数据

java 复制代码
public class Demo02Method {
    public static void main(String[] args) {
        method(new Supplier<String>() {
            /*
               get为重写方法:无参的,返回值为String的

               trim方法在get中:无参的,返回值为String的

               考虑用方法引用
             */
            @Override
            public String get() {
                return " abcd  ".trim();
            }
        });

        System.out.println("===================");

        method(()-> " abcd  ".trim());

        System.out.println("=========方法引用==========");

        method(" abcd  "::trim);

        System.out.println("===========================");


        method(new Supplier<String>() {
            /*
              get():空参,返回值类型为String
              toUpperCase:空参,返回值类型为String
             */
            @Override
            public String get() {
                return "abcdefg".toUpperCase();
            }
        });
        System.out.println("================");
        method(()->"abcdefg".toUpperCase());
        System.out.println("======方法引用=======");
        method("abcdefg"::toUpperCase);

        System.out.println("=======================");

        method(()->"abcdefg".substring(1));

        //method("abcdefg"::substring);

    }

    public static void method(Supplier<String> supplier){
        String s = supplier.get();
        System.out.println(s);
    }
}

4)类名-引用静态方法

类名--引用静态方法

格式:

类名::静态成员方法

java 复制代码
public class Demo03Method {
    public static void main(String[] args) {
        method(new Supplier<Double>() {
            /*
              get: 无参,返回值类型为Double
              random:无参,返回值类型为double
             */
            @Override
            public Double get() {
                return Math.random();
            }
        });

        System.out.println("======Lambda表达式======");

        method(()-> Math.random());

        System.out.println("======方法引用======");
        method(Math::random);
    }
    public static void method(Supplier<Double> supplier){
        Double s = supplier.get();
        System.out.println(s);
    }
}

5)类-构造引用

  1. 类--构造方法引用

格式:

构造方法名称::new

2.需求:

函数式接口:Function

java.util.function.Function<T,R>接口

抽象方法:

R apply(T t),根据类型T的参数获取类型R的结果。用于数类型转换

java 复制代码
public class Demo04Constructor {
    public static void main(String[] args) {
        method(new Function<String, Person>() {

            /*
               apply:有一个String参数,返回值为Person类型

               new Person(s): 一个参数的有参构造,参数为String,返回值类型为Person类型

               Person p = new Person(s)
             */
            @Override
            public Person apply(String s) {
                return new Person(s);
            }
        },"柳岩");

        System.out.println("======Lambda======");
        method(s -> new Person(s),"曼曼");

        System.out.println("======方法引用=====");

        method(Person::new,"曼曼");
    }

    public static void method(Function<String,Person> function,String name){
        Person person = function.apply(name);
        System.out.println(person);
    }
}

6)数组引用

数组--数组引用

格式:

数组的数据类型[]::new

int[]::new 创建一个int型的数组

double[]::new 创建于一个double型的数组

java 复制代码
public class Demo05Array {
    public static void main(String[] args) {
        method(new Function<Integer, int[]>() {
            /*
                apply:参数为Integer型,返回值类型为int[]

                new int[integer]:[integer]看成参数,参数为Integer型
                                 返回值类型为int[]
             */
            @Override
            public int[] apply(Integer integer) {
                return new int[integer];
            }
        },10);

        System.out.println("===========Lambda表达式=============");

        method(integer-> new int[integer],10);

        System.out.println("===========方法引用============");
        method(int[]::new,10);
    }
    public static void method(Function<Integer,int[]> function,Integer len){
        int[] arr = function.apply(len);
        System.out.println(arr.length);
    }
}
相关推荐
前行的小黑炭33 分钟前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
android·java·kotlin
Java技术小馆38 分钟前
如何设计一个本地缓存
java·面试·架构
XuanXu1 小时前
Java AQS原理以及应用
java
风象南4 小时前
SpringBoot中6种自定义starter开发方法
java·spring boot·后端
mghio13 小时前
Dubbo 中的集群容错
java·微服务·dubbo
咖啡教室18 小时前
java日常开发笔记和开发问题记录
java
咖啡教室18 小时前
java练习项目记录笔记
java
鱼樱前端19 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea19 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq