java基础-Java8新特性

Java8新特性


Lambda表达式

  • 面向对象的思想:,做一件事,找一个能解决这件事的对象,调用对象的方法完成事情
  • 函数式编程思想:只要能获取到结果,谁去做的怎么做的都不重要,重视的是结果不是过程

使用Lambda表达式

package com.z.lambda.testlambda;

public class Test2 {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hhh");
            }
        };
        new Thread(runnable).start();

        /*
            接口内的方法没有任何参数

            ():看要重写的方法有没有参数
            ->:lambda表达式的一个标识
            {}:代表了当前方法体 重写方法要做的内容

            ()->{System.out.println("hhh");}
        */
        new Thread(()->{System.out.println("哈哈哈");}).start();


        int a = 10;
        int b = 20;
     /*   show(a, b, new Calc() {
            @Override
            public int add(int a, int b) {
                return a+b;
            }
        });*/
//        show(a,b,(int c,int d)->{return c+d;});//30

        //可以省略形参类型:  接口中已经定义了方法的形参
//        show(100,120,(c,d)->{return c+d;});//220

        //当方法体只有一句代码的时候 可以省略return
        show(10,120,(c,d)->c+d);//130


    }
    static void show(int a,int b,Calc c){
        int add = c.add(a,b);
        System.out.println(add);

    }
}
interface Calc{
    int add(int a, int b);
}

函数式接口分类

1. 自定义函数式接口
  • 自定义函数式接口与已知函数接口
package com.z.lambda.func;
/*
    @FunctionalInterface
    检验当前接口是不是函数式接口:只能有一个抽象方法
    
    知道的函数式接口:Runnable   Comparator
*/
@FunctionalInterface//自定义函数接口
public interface Show {
    int NUM = 20;
    public void show();
    public static void showMessage(){
        System.out.println("this is showMessage()");
    }
    public default void c(){
        System.out.println("this is c()");
    }
}
2. 消费型接口
  • 消费型接口的抽象方法特点:有形参,但是返回值类型是void
    在这里插入图片描述
package com.z.lambda.consumer;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/*
    消费型接口:只进不出

*/
public class Test2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("李白");
        list.add("杜甫");
        list.add("王安石");
        list.add("白居易");
/*//      ↓ 四种遍历方式
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        for (String s : list) {
            System.out.println(s);
        }
        //迭代器
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        ListIterator<String> listIterator = list.listIterator();
        while(listIterator.hasNext()){
            System.out.println(listIterator.next());
        }*/

        /*//消费型接口
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        //使用lambda表达式简化
//        list.forEach((l)-> {System.out.println(l);});
        //当只有一个参数的时候 可以省略()
        list.forEach(l-> System.out.println(l));


        Map<Integer,String> map = new HashMap<>();
        map.put(10,"李白");
        map.put(11,"杜甫");
        map.put(12,"王安石");
        map.put(13,"李商隐");
        /*map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer key, String value) {
                System.out.println(key+"----->"+value);
            }
        });*/
        //使用lambda表达式简化
        map.forEach((k,v)->{System.out.println(k+"----->"+v);});
    }
}

3. 供给型接口
  • 供给型接口抽象方法特点:无参,但是有返回值
    在这里插入图片描述
package com.z.lambda.inter;

import java.util.function.Supplier;
import java.util.stream.Stream;

public class TestLambda {
    public static void main(String[] args) {
        Supplier<String> s = new Supplier<String>() {
            @Override
            public String get() {
                return "你好";
            }
        };
        System.out.println(s.get());

        //当没有形参的时候,不能省略()
        Supplier<String> s1 =()->"HelloWorld";
        System.out.println(s1.get());

//      无限流
/*
        Stream.generate(new Supplier<Double>() {
            @Override
            public Double get() {
                return Math.random();
            }
        }).forEach((a)->System.out.println(a));
*/

        Stream.generate(()->Math.random()).forEach((a)-> System.out.println(a));
    }
}

4. 判断型接口
  • 判断型接口的抽象方法特点:有参,但是返回值类型是boolean结果
    在这里插入图片描述
package com.z.lambda.judge;

import java.util.ArrayList;
import java.util.function.Predicate;

public class Test2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("李白");
        list.add("杜甫");
        list.add("李商隐");
        list.add("白居易");

        /*list.removeIf(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                if (s.startsWith("李")){
                    return true;
                }
                return false;
            }
        });*/
        
        /*list.removeIf(s -> {
            if (s.startsWith("李")){
                return true;
            }
            return false;
        });*/
//          三目运算符简化
        list.removeIf(s -> s.startsWith("李") ? true : false);
        System.out.println(list);
    }
}

5. 功能型接口
  • 功能型接口的抽象方法特点:既有参数又有返回值
package com.z.lambda.function;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

public class Test2 {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();
        map.put(10,"李白");
        map.put(12,"杜甫");
        map.put(13,"李商隐");
        map.put(14,"白居易");
/*        map.replaceAll(new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer integer, String s) {
                if (s.startsWith("李")){
                    return "hahah";
                }
                return null;
            }
        });*/
        map.replaceAll((key,value)->{
            if (value.startsWith("李"))
            {
                return "lalal";
            }
            return null;
        });
        System.out.println(map);//{10=lalal, 12=null, 13=lalal, 14=null}
    }
}

方法引用与构造器引用

  • Lambda表达式是可以简化函数式接口的变星与形参赋值的语法。而方法引用和构造器引用是为了简化Iambda表达式的。当Lambda表达式满足一些特殊的情况时,还可以再简化:

    1. Lambda体只有一句语句,并且是通过调用一个对象的/类现有的方法来完成的
      例如: System.out对象,调用println()方法来完成Lambda体
      Math类,调用random()静态方法来完成Lambda体
    2. 并且Lambda表达式的形参正好是给该方法的实参
      例如: t->System.out.printIn(t)
      ()-> Math.random()都是无参
方法引用
  • 方法引用的作用:简化Lambda表达式
  • 方法引用的语法格式:
    1. 实例对象名::实例方法
    2. 类名::静态方法
    3. 类名::实例方法
  • 说明:
    1. ::称为方法引用操作符(两个:中间不能有空格,而且必须英文状态下半角输入)
    2. Lambda表达式的形参列表,全部在Lambda体中使用上了,要么是作为调用方法的对象,要么是作为方法的实参。
    3. 在整个Lambda体中没有额外的数据。
package com.z.lambda.method;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class TestMethod {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("李白");
        list.add("杜甫");
        list.add("白居易");
        list.add("李商隐");
/*        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        /*list.forEach(s-> System.out.println(s));*/

        list.forEach(System.out::println);

//      方法引用1
        Employee e = new Employee(1, "李白", "男", 19, 9889);
        /*Supplier<String> name = new Supplier<String>() {
            @Override
            public String get() {
                return e.getName();
            }
        };*/
//        Supplier<String> name = ()->e.getName();
        //实例对象名::实例方法(实例对象名调用实例方法)
        Supplier<String> name = e::getName;
        System.out.println(name.get());

//方法引用2
        /*Stream.generate(new Supplier<Double>() {
            @Override
            public Double get() {
                return Math.random();
            }
        }).forEach(System.out::println);*/
//        Stream.generate(() -> Math.random()).forEach(System.out::println);
        //类名::静态方法(类名调用静态方法)
        //Stream.generate(Math::random).forEach(System.out::println);

//方法引用3
        String[] arr = {"c","d","a","z","e"};
        /*Arrays.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });*/
//        Arrays.sort(arr,((o1, o2) -> o1.compareTo(o2)));
        //类名::实例方法(类调用实例方法)
        Arrays.sort(arr,String::compareTo);
        System.out.println(Arrays.toString(arr));
    }
}

class Employee {
    private int no;
    private String name;
    private String sex;
    private int age;
    private double salary;

    public Employee() {
    }

    public Employee(int no, String name, String sex, int age, double salary) {
        this.no = no;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.salary = salary;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}
构造器引用
  • 当Lambda表达式是创建一个对象,并且满足Lambda表达式形参,正好是给创建这个对象的构造器的实参列表。
  • 当Lambda表达式是创建一个数组对象,并且满足Lambda表达式形参,正好是给创建这个数组对象的长度构造器引用的语法格式:
    1. 类名::new
    2. 数组类型名::new
package com.z.lambda.constru;

import java.util.function.Function;
import java.util.function.Supplier;

public class Test2 {
    public static void main(String[] args) {
        //构造器引用
        /*Supplier<Employee> e = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee();
            }
        };*/
        //类名::new
        Supplier<Employee> e =Employee::new;
                System.out.println(e.get());


        Function<Integer,int []> f = new Function<Integer, int[]>() {
            @Override
            public int[] apply(Integer integer) {
                return new int[integer];
            }
        };
        int[] apply = f.apply(20);
        System.out.println(apply.length);
        //数组类型名::new
        Function<Integer,int []> f1 = int[]::new;
        int[] apply1 = f1.apply(10);
        System.out.println(apply1.length);
    }
}
class Employee {
    private int no;
    private String name;
    private String sex;
    private int age;
    private double salary;

    public Employee() {
    }

    public Employee(int no, String name, String sex, int age, double salary) {
        this.no = no;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.salary = salary;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}

Stream API

  • 注意:
    1. Stream自己不会存储元素。
    2. Stream不会改变源对象。每次处理都会返回一个持有结果的新Stream。
    3. stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
  • Stream的操作三个步骤:
    • 创建Stream:通过一个数据源(如:集合、数组),获取一个流
    • 中间操作:中间操作是个操作链,对数据源的数据进行n次处理,但是在终结操作前,并不会真正执行。
    • 终止操作:一旦执行终止操作,就执行中间操作链,最终产生结果并结束Stream,
      在这里插入图片描述

创建Stream

  1. 创建Stream方式一:通过集合
    Java8中的Collection接口被扩展,提供了两个获取流的方法:
  • public default Stream<E> stream():返回一个顺序流
  • public default Stream<E> parallelStream():返回一个并行流
package com.z.stream;

import java.util.ArrayList;
import java.util.stream.Stream;

public class CreateStream {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
/*通过集合*/
        Stream<Integer> stream = list.stream();
        //获取并行流
//        Stream<Integer> stream = list.parallelStream();
        // 方法引用
//        stream.forEach(System.out::println);
        stream.forEach((t)->{
            System.out.println(Thread.currentThread().getName()+"===>"+t);
        });
  	}
}
  1. 创建Stream方式二:通过数组

Java8中的Arrays 的静态方法 stream()可以获取数组流:

  • public static <T> Stream<T> stream(T[] array):返回一个流
    重载形式,能够处理对应基本类型的数组:
  • public static IntStream stream(int[] array):返回一个整型数据流
  • public static LongStream stream(long[] array):返回一个长整型数据流
  • public static DoubleStream stream(double[] array):返回一个浮点型数据流
package com.z.stream;

import java.util.Arrays;
import java.util.stream.Stream;

public class CreateStream {
    public static void main(String[] args) {
        
        int [] arr = {20 ,50,40,30,12};
        Arrays.stream(arr).forEach(System.out::println);
    }
}
  1. 创建Stream方式三:通过Stream的of()
    可以调用Stream类静态方法of(),通过显示值创建一个流。它可以接收任意数量的参数。
  • public static<T> Stream<T> of(T… values):返回一个顺序流
// 创建流↓                         遍历↓
Stream.of(10,20,40,30).forEach(System.out::println);
  1. 创建Stream方式四:创建无限流
    可以使用静态方法Stream.iterate()和Stream.generate(),创建无限流。
  • public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f):返回一个无限流
  • public static<T> Stream<T> generate(Supplier<T> s):返回一个无限流
 //无限流
        /*Stream.iterate(1, new UnaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer) {
                return 10;
            }
        }).forEach(System.out::println);*/
//        Stream.iterate(1, (t)->t+=1).forEach(System.out::println);
        Stream.generate(Math::random).forEach(System.out::println);

中间操作

package com.z.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.stream.Stream;

/*
    1. 不会对原有数据造成影响
    2. 中间操作的流 和 终结操作的流 必须是同一个流
*/
public class MiddleTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();
        list.add(10);
        list.add(21);
        list.add(30);
        list.add(43);
        list.add(50);
        //1. 创建流
        Stream<Integer> stream = list.stream();
        /*stream.filter(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return false;
            }
        });*/
        System.out.println("========去掉偶数只保留奇数==========");

        //去掉偶数只保留奇数
        Stream<Integer> integerStream = stream.filter((s) -> s % 2 != 0);
        integerStream.forEach(System.out::println);
        System.out.println("========去掉奇数只要偶数==========");
        //去掉奇数只要偶数
        list.stream().filter((s) -> s % 2 == 0).forEach(System.out::println);
        System.out.println("========从小到大排序==========");

        //从小到大排序
        list.stream().sorted().forEach(System.out::println);
        System.out.println("==========从大到小排序========");

        //从大到小排序
        /*list.stream().sorted(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return -o1.compareTo(o2);
            }
        }).forEach(System.out::println);*/
        list.stream().sorted((a,b)-> {return b.compareTo(a);}).forEach(System.out::println);
        System.out.println("==========拿前两数========");
//      limit(2):限制:取前俩个
        list.stream().sorted((a,b)-> {return b.compareTo(a);}).limit(2).forEach(System.out::println);
        System.out.println("==========拿第2个数,不要第一个========");
        //skip(1 ):跳过一个
        list.stream().sorted((a,b)-> {return b.compareTo(a);}).limit(2).skip(1 ).forEach(System.out::println);

        System.out.println("=================");
        String[] arr = {"hello","world","hero"};
        //映射关系
        Arrays.stream(arr).map((s) -> s.toUpperCase()).forEach(System.out::println);

        System.out.println("=========distinct():去除重复元素========");
        Stream.of(1,2,3,3,2,1,10,20).distinct().forEach(System.out::println);
    }
}

终结操作

package com.z.stream;

import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/*  中间操作可以有多个,但是终结操作只能有一个*/
public class EndTest {
    public static void main(String[] args) {
        long count = Stream.of(10, 20, 30, 1, 1, 2, 3, 4, 5, 7).filter((s) -> s % 2 != 0).peek(System.out::println).count();
        System.out.println("------>" + count);
        /*  1
            1
            3
            5
            7
            ------>5
*/
        System.out.println("======allMatch  判断所有元素是否都是10=======");
        System.out.println("======anyMatch  任意一个元素是否是10=======");
        System.out.println("======noneMatch  没有一个元素是10=======");
        boolean b = Stream.of(10, 20, 30, 1, 1, 2, 3, 4, 5, 7).noneMatch((s) -> s == 10);
        System.out.println(b);//false

        Optional<Integer> first = Stream.of(10, 20, 30, 1, 1, 2, 3, 4, 5, 7).findFirst();
        System.out.println(first.get());//10

        /*collect:将满足要求的数据  进行收集*/
        List<Integer> collect = Stream.of(10, 20, 30, 1, 1, 2, 3, 4, 5, 7).filter((s) -> s % 2 == 0).collect(Collectors.toList());
        System.out.println(collect);//[10, 20, 30, 2, 4]

        //将值反复结合,最终变为一个值
/*        Optional<Integer> reduce = Stream.of(10, 20, 30).reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        });*/
        Optional<Integer> reduce = Stream.of(10, 20, 30).reduce((s, s1) -> s + s1);
        System.out.println(reduce.get());//60

    }
}

Optional

package com.z.op;

import java.util.Optional;

public class OpTest {
    public static void main(String[] args) {
        String s = null;
        Optional<String> s1 = Optional.ofNullable(s);
        System.out.println(s1);//Optional.empty 防止空指针
        System.out.println(s1.orElse("世界"));//世界

        String s2 = "你好";
        Optional<String> s21 = Optional.ofNullable(s2);
        System.out.println(s21.orElse("世界"));//你好


        Student student  = new Student();
        Optional<String> name = getName(student);
        System.out.println(name.orElse("张三"));//orElse("张三")避免空


    }
    public  static  Optional<String> getName (Student s){
        return Optional.ofNullable(s.name);//ofNullable避免空值
    }
}
class Student{
    String name ;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值