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);
    }
}
相关推荐
数据小爬虫@2 分钟前
如何利用java爬虫获得淘宝商品评论
java·开发语言·爬虫
喜欢猪猪3 分钟前
面试题---深入源码理解MQ长轮询优化机制
java
qq_172805599 分钟前
RUST学习教程-安装教程
开发语言·学习·rust·安装
wjs202417 分钟前
MongoDB 更新集合名
开发语言
monkey_meng20 分钟前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
草莓base33 分钟前
【手写一个spring】spring源码的简单实现--bean对象的创建
java·spring·rpc
legend_jz1 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
drebander1 小时前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天2491 小时前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn1 小时前
java入门 自定义springboot starter
java·开发语言·spring boot