Java新特性(jdk8)

第一章-lambda表达式

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

1.面向对象思想:
  强调的是找对象,帮我们去做事儿
      
  比如:去北京   -> 强调的是怎么去,火车,高铁,飞机,汽车,自行车,腿儿   
      
      
2.jdk8开始有了一个新的思想:函数式编程思想:
  强调的是结果,不强调过程
      
  比如:去北京 -> 只强调去了还是没去
      
3.Lambda表达式语法:
  a.定义格式:
    ()->{}
  b.各部分解释:
    () : 重写方法的参数位置
    -> : 将参数传递到方法体中
    {} : 重写方法的方法体位置

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可以干掉

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 +
                '}';
    }
}
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

@FunctionalInterface
public interface USB {
    void open(String s);
    //void close();
}
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.泛型:
  <引用数据类型>-> 规定了我们操作的数据是什么类型
  <>中只能写引用数据类型,不能写基本数据类型

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方法之后,方法体怎么写了

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的结果

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型

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流

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)

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流不能用了

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也是一个终结方法

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.作用:根据某个条件进行元素过滤

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流对象

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流对象

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):两个流合成一个流

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

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

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)方法引用的体验

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方法获取一个什么类型的数据

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)类名-引用静态方法

类名--引用静态方法
    格式:
      类名::静态成员方法

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的结果。用于数类型转换

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型的数组

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);
    }
}

  • 26
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值