JDK1.8新特性

JDK1.8 接口的新特性

接口中 默认方法可以覆盖 静态方法不可以覆盖

在JDK1.8中对接口的一些改动。

  1. 函数式接口的注解@FunctionalInterface

    函数式接口的概念:只有一个抽象方法的接口,其中抽象接口的接口名不能和Object中的方法重名。

    若重名则这个接口不能算是函数式接口。

  2. 接口内的default 方法和static 方法

总结

1)接口中的abstract抽象方法通过实例对象来调用;

2)接口中的default方法通过实例对象来调用;

3)接口中的静态方法通过接口名.方法名()的方式来调用;

4)接口是不允许直接使用new的方式来获取实例的,如果new可以使用匿名实现类的方式:new后面跟上一对花括号来实现接口中的抽象方法。(匿名实现类:顾名思义没有名称的实现类,优点是不用再单独声明一个类;缺点是没有名字,不能重复使用,只能使用一次。)

其中@FunctionalInterface注解表示:

通过JDK8源码javadoc,可以知道这个注解有以下特点:

1、该注解只能标记在"有且仅有一个抽象方法"的接口上。

2、JDK8接口中的[静态方法和默认方法](http://blog.youkuaiyun.com/aitangyong/article/details/54134385),都不算是抽象方法。

3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。

4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。

lambda

在之前我们使用接口的方法的时候需要使用接口的实现类

当接口只使用一次 我们就不必创建实现类来使用接口方法

可以使用匿名内部类

//接口  A 
@FunctionalInterface
    interface A {
        void ser(int a,int b);
    }

匿名内部类的使用方式

        A a = new A() {
            @Override
            public void ser() {
                System.out.println(11111);
            }
        };
        a.ser();

使用lambda

1.无参数

//JDK1.8的新特性 lambda
A a1 = ()-> System.out.println(123);
//就可以直接来使用接口的实现方法
a1.ser();

2.有参数

//当接口方法需要参数的时候
//直接在括号里面写入类型 和参数名就可以
A a2 = (int a,int b)-> System.out.println("a:"+a+",b:"+b);
a2.ser(10,20);

3.当方法里面需要写入多行代码时

//当我们需要在实现方法里面写多行代码的时候怎么办呢?
//可以使用{}  把代码写入里面 就可以了
A a3 = (int a,int b)->{
	System.out.println(a);
	System.out.println(b);
};
a3.ser(1,2);

4.当方法有返回值的时候

//方式一
A a4 = (int a,int b)->a+b;
int ser = a4.ser(10, 20);
System.out.println(ser);
//方式二
A a4 = (int a,int b)->{
    return a+b
};
int ser = a4.ser(10, 20);
System.out.println(ser);

5.遍历集合

		List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
        //第一种 jdk1.8新特性之前的写法
        for (Integer integer : list) {
            System.out.println(integer);
        }
        System.out.println("==========================");
        //第二种  使用lambda表达式
        Consumer<Integer> action = (t)-> System.out.println(t);
        list.forEach(action);
        System.out.println("==========================");
        //还可以这样写  在方法里面把lambda写入
        list.forEach(t-> System.out.println(t));

        System.out.println("===========================");
        //第三种  使用方法引入
        list.forEach(System.out::println);
        

使用lambda实现接口

1.consumer接口

参数列表 T 返回值类型 void

Consumer<String> consumer = (String s)->{
            String[] split = s.split(",");
            for (String s1 : split) {
                System.out.println(s1);
            }
        };
        consumer.accept("10,20,30,40,50");

2.Predicate接口

参数列表 T 返回值类型 boolean

 //实现Predicate
        Predicate<String> predicate = (String string)->{
            /*
            * endsWith是用来判断里面的字符串是否是最后一个
            * 比如lanqiao  o是否是最后一个 是就返回ture 反之返回false
            * 长字符串同理  lanqiao  放入 qiao 也返回true 但放入 qia 就会返回false
            * contains方法可以判断输入的字符串是否存在比对的字符串里面
            * */
            if(string.endsWith("qia")){
                return true;
            }else {
                return false;
            }
        };
        System.out.println(predicate.test("lanqiao"));
        

3.Function接口

参数列表 T 返回值类型 R

	Function<String,Integer> function = (string)-> Integer.parseInt(string);
        System.out.println(function.apply("123"));
        

4.Supplier接口

参数列表 void 返回值类型 T

	Supplier<User> supplier = ()-> new User();

    System.out.println(supplier.get().toString());

案例

  public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(10, 20, 30, 40, 50, 60,70,80);
        /*
        * 方法wapperList的两个参数
        * 参数一:List类型 代表成绩的集合
        * 参数二:Function接口类型,
        *   我们就可以通过重写function来对集合中的成绩进行任意的操作
        * */

        List<Integer> integerList = wapperList(integers, (integer) -> {
            //在这里我们就重写了function  让每个成绩都加了5
            return integer + 5;
        });

        //遍历
        for (Integer integer : integerList) {
            System.out.println(integer);
        }

    }

    //这个方法的作用就是把集合成绩抽出来
    public static<R,T> List<T> wapperList(List<T> list, Function<T,R> function){
        //使用新的数组来存储
        LinkedList<T> linkedList = new LinkedList<>();
        for (T l : list) {
           /*
           * 在添加成绩的时候使用了function被重写以后里面的方法
           * 在这里通过重写Function接口来对每一个人的成绩进行修改
           * */
            linkedList.add((T) function.apply(l));
        }
        return linkedList;
    }

*方法引入

1.静态方法引用 类名::静态方法

2.对象方法引用 对象名::成员方法

3.类构造器引用 类名::new

4.数组构造器引用 类型名[]::new

*只要是返回值 和参数列表相同 就可以使用

//例如 Consumer类
void accept(T var1);

		List<Integer> integers = Arrays.asList(10, 20, 30, 40, 50);
        Consumer<Integer> consumer = (Integer num)-> System.out.println(num);
        //println的方法参数和返回值和consumer的参数和返回值相同  我们就可以直接使用println方法来替代
        integers.forEach(System.out::println);
        

1.静态方法引用

  static class B{
        public static int abs(int num){
            return Math.abs(num);
        }
    }


    public static void main(String[] args) {
        A a1 = B::abs;
        System.out.println(a1.abs(-10));
    }

2.对象方法引用

	interface A{
         int abs(int number);
    }

    public static void main(String[] args) {
        //只要是返回值 和参数列表相同 就可以使用
        A a = Math::abs;//等同于 A a = num-> Math.abs(num)
        int abs = a.abs(-12);
        System.out.println(abs);
    }
 list.forEach(System.out::println);//System.out其实是一个对象,就是调用了println这个方法来打印
//他的效果和 下面这个一样
list.forEach(t-> System.out.println(t));

Optional

简介

从 Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException)

本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。

Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。但是 Optional 的意义显然不止于此。

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional 类的引入很好的解决空指针异常。

方法

empty

//源码
private static final Optional<?> EMPTY = new Optional();

	public static <T> Optional<T> empty() {
        Optional<T> t = EMPTY;
        return t;
    }

一般是用于创建Optional对象

	 Optional<Object> optional = Optional.empty();//emppty--》 new Optional();
     System.out.println(optional);//Optional.empty
     

of

    //源码
	public static <T> Optional<T> of(T value) {
        return new Optional(value);
    }

存入Value值到Optional

Optional<String> optional = Optional.of(null);

//获取到的值:Optional[123]

如果存入的值是 null 就会抛出异常

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XSaC8W5-1619322479432)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201223173846031.png)]


get()

//源码	
public T get() {
        if (this.value == null) {
            throw new NoSuchElementException("No value present");
        } else {
            return this.value;
        }
    }

使用get方法获取到的就是具体的值

		Optional<String> optional = Optional.of("123");
        System.out.println(optional.get());

		//获取到的值是:123

ofNullable

    //源码
	public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

如果不是null 就返回自己的值 反之创建 Optional对象

		Optional<String> optional = Optional.ofNullable(null);//如果不是null 就会返回Optional[传入的值]
        System.out.println(optional);//Optional.empty
        

ifPresent

判断值是否为null 不为null就返回 为null就不管

Consumer

    //源码
	public void ifPresent(Consumer<? super T> action) {
        if (this.value != null) {
            action.accept(this.value);
        }
    }

如果传入Optional的值不为null 那么就会使用我们传入(consumer接口)的

		List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        Optional<List<Integer>> optional = Optional.ofNullable(integers);
		        

		//lambda使用
        optional.ifPresent(t-> System.out.println(t));
        //对象::方法
        optional.ifPresent(System.out::println);

		//上面两种遍历方式效果都一样  只是使用方式不同
		

isPresent

    //源码
	public boolean isPresent() {
        return this.value != null;
    }

判断Optional是否为空 为空就会返回false 反之返回true

	Optional<String> optional = Optional.ofNullable("abc");//传入的是null  返回的就是false 反之true

    boolean present = optional.isPresent();
    

map

Function

 public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
     				
        return !this.isPresent() ? empty() : ofNullable(mapper.apply(this.value));
      
    }
    

map主要是配合着(Function接口)来使用

判断传入map的值是否为空 空就创建Optional

		Optional<List<Integer>> optional = Optional.ofNullable(integers);
											//不为空 就执行括号里面的lambda方法
        Optional<String> optionalS = optional.map(t -> "abc");
        

filter

Predicate接口

public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!this.isPresent()) {
            return this;
        } else {
            	//在这里就是使用Predicate接口
            return predicate.test(this.value) ? this : empty();
        }
    }
        String str = "132";

        Optional<String> optional = Optional.ofNullable(str);//如果Optional为空会执行 if的语句  反之执行else的语句
								//这里就是predicate接口的具体实现
        Predicate<String> predicate = t->true;//这里的值决定 predicate.test(this.value)的值
													
        Optional<String> optionalS = optional.filter(predicate);

        System.out.println(optionalS);
        

orElse

    public T orElse(T other) {
        return this.value != null ? this.value : other;
    }
		Cat cat_1 = new Cat(1,"第一只",10);
        Cat cat_2 = new Cat(2,"第二只",20);
        Cat cat_3 = new Cat(3,"第三只",30);
        List<Cat> cats = Arrays.asList(cat_1, cat_2, cat_3);
//        Person person = new Person(1, "张三", cats);
        Person person = new Person();

        //传入值
        Optional<Person> optional = Optional.ofNullable(person);
        //获取到person类里面的 list集合  orElse判断集合是否是null  是null就执行方法括号里面的内容
        List<Cat> cats1 = optional.map(Person::getCatList).orElse(Collections.emptyList());
        System.out.println(cats1);

		//该方法的作用是 提供一个空的list集合
		Collections.emptyList()
		

Cat类

	private Integer id;
    private String name;
    private Integer age;	

Person类

    private Integer id;
    private String name;
    private List<Cat> catList;

orElseGet

Supplier

 public T orElseGet(Supplier<? extends T> supplier) {
        return this.value != null ? this.value : supplier.get();
    }
    

判断Optional是否为null 不为空就注解把值返回回去 为空就值Supplier接口被实现的方法

		Optional<String> optional = Optional.ofNullable("123");//如果传入的是null 那么最后打印的是abc  反之打印123
        String s = optional.orElseGet(() -> "abc");
        System.out.println(s);
        

案例

        String str = "abc";
        Optional<String> optional = Optional.ofNullable(str);
        String main = optional.filter(
                t -> !(t.equals(""))).map(
                        t -> "123").orElseGet(
                                () -> "login");
        System.out.println(main);

Stream

常用方法

	skip 跳过
	concat合并流
    limit 分页
    distinct  去重
    sorted  排序
    parallel  并行
    findFirst  	获取到数组的第一个元素
    findAny		获取到运行时第一个元素
    count  计数

需要注意的是Map集合不能直接调用stream 需要Stream的of方法来转换

集合

		//List Stream
        List<Integer> integers = Arrays.asList(10, 20, 30, 40, 50);
        Stream<Integer> stream1 = integers.stream();

        //set
        Set<Integer> set = new HashSet<>();
        Stream<Integer> stream = set.stream();

        //map  map不能直接调用stream方法  想要转为流 需要Stream的of方法
        Map<String,Integer> map = new HashMap();
        Stream<Map<String, Integer>> map1 = Stream.of(map);
        

数组

        //数组集合
        //Integer
        Integer[] integers1 = new Integer[]{1,2,3,4,5};
        Stream<Integer> stream3 = integers.stream();

        //int
        int[] ints = new int[]{1,2,3};
        IntStream stream4 = Arrays.stream(ints);

        //string
        String[] strings = new String[]{"a","b","c","d"};
        Stream<String> stream2 = Arrays.stream(strings);



of方法

        //Stream调用of方法
        Stream<int[]> ints1 = Stream.of(ints);

        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);

        Stream<String> a = Stream.of("a", "b");

Stream的中间操作与终结操作

终结操作和中间操作的区别

中间操作:流从源头到结束的过程中所进行的操作 都为中间操作  并且只要不执行终结操作,那么流就一直会执行。

终结操作:使用了终结操作,那么流就结束了,不能在执行中间操作**

常用的终结操作有:forEach,ifPresent

在不使用终结操作

public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);
	
        Stream<Integer> stream = integers.stream().filter(num -> num >= 3);

        Stream<Integer> integerStream = stream.filter(num -> num < 6);

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

    }

使用终结操作后再继续继续中间操作

public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6);

        Stream<Integer> stream = integers.stream().filter(num -> num >= 3);
        stream.forEach(System.out::println);//终结操作
        
        Stream<Integer> integerStream = stream.filter(num -> num < 6);

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

    }

串行与并行

findFirst

	Stream.of(1,3,4,2,67,25).parallel() //把串行该为并行
                .findFirst()    //获取到数组的第一个元素
                .ifPresent(System.out::println);

findAny

        Stream.of(3,4,64,16,431,4).parallel()
                .findAny()      //获取到运行时第一个元素
                .ifPresent(System.out::println);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值