专栏首页csicoJava8新特性

Java8新特性

接口中默认方法修饰为普通方法#

在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的,由于这些修饰符都是默认的。

接口定义方法:public 抽象方法 需要子类实现

接口定义变量:public、static、final

在JDK 1.8开始 支持使用static和default 修饰 可以写方法体,不需要子类重写。

方法:

普通方法 可以有方法体

抽象方法 没有方法体需要子类实现 重写。

案例

public interface JDK8Interface {
    /*
    * 默认就是public abstract  JDK7之前不能有方法体
    * */
    void add();

    /*
    * jdk8 提供默认实现
    * */
    default void  get() {
        System.out.println("default方法可以写方法体");
    }

    static void getStaticOrder() {
        System.out.println("静态方法可以写方法体");
    }
}

子类实现接口

public class JDK8InterfaceImpl implements  JDK8Interface {
    /*
    * 子类实现接口 没有强制要求重写default和static方法
    * */
    @Override
    public void add() {
        System.out.println("add方法");
    }

}

方法调用

public class Test01 {
    public static void main(String[] args) {
        JDK8Interface jdk8Interface=new JDK8InterfaceImpl();
        jdk8Interface.add();
        jdk8Interface.get();

        JDK8Interface.getStaticOrder();
    }
}

Lambda表达式#

是一个匿名函数,简化我们调用匿名函数的过程

Lambda好处: 简化我们匿名内部类的调用。

Lambda+方法引入 代码变得更加精简。

    public static void main(String[] args) {
        //使用匿名内部类的方式调用
//        new OrderService(){
//            @Override
//            public void addOrder() {
//                System.out.println("addorder");
//            }
//        }.addOrder();
        ((OrderService) () -> System.out.println("addorder")).addOrder();

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println(Thread.currentThread().getName()+"运行");
//            }
//        }).start();
        new Thread(() -> System.out.println(Thread.currentThread().getName()+"运行")).start();

    }

Lambda表达式的规范#

使用Lambda表达式 依赖于函数接口

  1. 在接口中只能够允许有一个抽象方法
  2. 在函数接口中定义object类中方法
  3. 使用默认或者静态方法
  4. @FunctionalInterface 表示该接口为函数接口

Java中使用Lambda表达式的规范,必须是为函数接口

函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口

@FunctionalInterface
public interface MyFunctionalInterface {

    void  get();

    default void add() {

    }
    String toString();
}

常见例如Runnable接口

方法调用

    public static void main(String[] args) {
        ((MyFunctionalInterface) () -> System.out.println()).get();
    }

Lambda基础语法#

()--参数列表
-> 分隔
{}  方法体

(函数接口的参数列表 不需要写类型 需要定义参数名称)->{方法体}

无参方法调用#

@FunctionalInterface
public interface MyFunctionalInterface {
    void  get();
}

MyFunctionalInterface myFunctionalInterface= ()->{
     System.out.println("使用lambda表达式");
};

有参带返回值调用#

@FunctionalInterface
public interface YouFunctionalInterface {
    String get(int i,int j);
}
    public static void main(String[] args) {
        YouFunctionalInterface youFunctionalInter=(i, j)->{
            return i+"--"+j;
        };
        System.out.println(youFunctionalInter.get(1, 1));
    }

精简版#

public static void main(String[] args) {
        //无参方法原始版本
        MyFunctionalInterface functionalInterface=()->{
            System.out.println("");
        };
        functionalInterface.get();
        //精简版1
        ((MyFunctionalInterface)()->{
            System.out.println("");
        }).get();
        //精简版2 在方法体只有一条语句的时候,不需要写大括号了
        MyFunctionalInterface functionalInterface2=()-> System.out.println("");
        //最终精简版3
        ((MyFunctionalInterface)()-> System.out.println("")).get();


        //有参方法
        YouFunctionalInterface youFunctionalInterface=(int i,int j)->{
            return "";
        };
        String s = youFunctionalInterface.get(2, 3);

        //精简版1
        YouFunctionalInterface youFunctionalInterface1=( i, j)->{
            return "";
        };

        //精简版2
        YouFunctionalInterface youFunctionalInterface2=(i, j)-> i+"--"+j;
        String s1 = youFunctionalInterface1.get(2, 3);

        //最终精简版3
        String s2 = ((YouFunctionalInterface) (i, j) -> i + "--" + j).get(1, 2);
        System.out.println(s2);
    }

Lambda实战案例#

Foreach#

    public static void main(String[] args) {
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("111");
        arrayList.add("222");
        arrayList.add("333");

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

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

Lambda集合排序#

public class UserEntity {
    private String name;
    private Integer age;

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

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "UserEntity{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 public static void main(String[] args) {
        ArrayList<UserEntity> userlists = new ArrayList<>();
        userlists.add(new UserEntity("aa", 22));
        userlists.add(new UserEntity("bb", 18));
        userlists.add(new UserEntity("cc", 36));

        userlists.sort(new Comparator<UserEntity>() {
            @Override
            public int compare(UserEntity o1, UserEntity o2) {
                return o1.getAge()- o2.getAge();
            }
        });

        //精简遍历
        userlists.forEach(s-> System.out.println(s));

        //精简排序
        userlists.sort((o1, o2) -> o1.getAge()- o2.getAge());
    }

Java 8 stream流#

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等

Stream :非常方便精简的形式遍历集合实现 过滤、排序等

Stream创建方式#

parallelStream为并行流采用多线程执行

Stream采用单线程执行

parallelStream效率比Stream要高

Stream将list转换为set#

  public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream=userEntities.stream();
        Set<UserEntity> collect = stream.collect(Collectors.toSet());
        collect.forEach(s-> System.out.println(s));

    }

set集合底层依赖于map 集合,map集合底层基于equals和hashcode比较防止重复

Stream将list转换为map#

public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        /*
        * list集合只有key  list转换map的时候需要指定key value,key=username  value=user对象
        * */
        Stream<UserEntity> stream=userEntities.stream();
        Map<String,UserEntity> collect = stream.collect(Collectors.toMap(new Function<UserEntity,String>() {
            @Override
            public String apply(UserEntity o) {
                return o.getName();
            }
        }, new Function<UserEntity, UserEntity>() {
            @Override
            public UserEntity apply(UserEntity usrentity) {
                return usrentity;
            }
        }));

        //精简版
        collect.forEach(new BiConsumer<String, UserEntity>() {
            @Override
            public void accept(String s, UserEntity userEntity) {
                System.out.println(s+","+userEntity);
            }
        });
        //最终精简版
        collect.forEach((BiConsumer)(s,userEntity)->System.out.println(s+","+userEntity));
    }

Stream将Reduce 求和#

  public static void main(String[] args) {
        Stream<Integer> integerStream=Stream.of(5,6,7,8);
        Optional<Integer> reduce = integerStream.reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        });
        System.out.println(reduce);

        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Optional<UserEntity> sum=userEntities.stream().reduce(new BinaryOperator<UserEntity>() {
            @Override
            public UserEntity apply(UserEntity userEntity, UserEntity userEntity2) {
                UserEntity userEntity1=new UserEntity("sum",userEntity.getAge()+userEntity2.getAge());
                return userEntity1;
            }
        });
        System.out.println(sum);
    }

Stream求最大最小#

    public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream=userEntities.stream();
        Optional<UserEntity> min = stream.min(new Comparator<UserEntity>() {
            @Override
            public int compare(UserEntity o1, UserEntity o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println(min.get());

        //简化版
        Optional<UserEntity> min1 = stream.min((o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println(min1.get());
    }

Stream Match 匹配#

anyMatch表示,判断的条件里,任意一个元素成功,返回true

allMatch表示,判断条件里的元素,所有的都是,返回true

noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

  public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream=userEntities.stream();

        boolean b = stream.anyMatch(new Predicate<UserEntity>() {
            @Override
            public boolean test(UserEntity userEntity) {
                return "aa".equals(userEntity.getName());
            }
        });
        System.out.println(b);

        //简化版
        boolean b1 = stream.anyMatch((userEntity) -> "aa".equals(userEntity.getName()));
        System.out.println(b1);
    }

Stream for循环#

    public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream=userEntities.stream();
        stream.forEach((userEntity -> System.out.println(userEntity)));
    }

Stream filter过滤器#

    public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream=userEntities.stream();
        stream.filter(new Predicate<UserEntity>() {
            @Override
            public boolean test(UserEntity userEntity) {
                return "aa".equals(userEntity.getName()) && userEntity.getAge() >= 18;
            }
        }).forEach((userEntity -> System.out.println(userEntity)));

        //精简版
        stream.filter((userEntity)->"aa".equals(userEntity.getName()) && userEntity.getAge() >= 18)
                .forEach((userEntity -> System.out.println(userEntity) ));
    }

Stream limit和skip#

Limit 从头开始获取

Skip 就是跳过

    public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("aa", 20));
        userEntities.add(new UserEntity("bb", 28));
        userEntities.add(new UserEntity("cc", 35));
        userEntities.add(new UserEntity("dd", 16));

        Stream<UserEntity> stream = userEntities.stream();
        stream.skip(2).limit(2).forEach((userEntity -> System.out.println(userEntity)));
    }

stream 综合案例#

 public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("mayikt", 20));
        userEntities.add(new UserEntity("meite", 28));
        userEntities.add(new UserEntity("zhangsan", 35));
        userEntities.add(new UserEntity("xiaowei", 16));
        userEntities.add(new UserEntity("mayikt_list", 109));
        userEntities.add(new UserEntity("mayikt_zhangsan", 110));
        userEntities.add(new UserEntity("lisi", 109));
        userEntities.add(new UserEntity("mayikt", 100));
        userEntities.add(new UserEntity("mayikt", 60));


        Stream<UserEntity> stream=userEntities.stream();
        stream.sorted((o1,o2)->o1.getAge()-o2.getAge())
                .filter((userEntity -> "mayikt".equals(userEntity.getName())))
                .limit(3)
                .forEach((userEntity)-> System.out.println(userEntity));
    }

并行流与串行流区别#

串行流:单线程的方式操作; 数据量比较少的时候。

并行流:多线程方式操作;数据量比较大的时候

原理:Fork join 将一个大的任务拆分n多个小的子任务并行执行,最后在统计结果,有可能会非常消耗cpu的资源,确实可以提高效率。

注意:数据量比较少的情况下,不要使用并行流

方法引用#

什么是方法引入

方法引入:需要结合lambda表达式能够让代码变得更加精简

  1. 静态方法引入: 类名::(静态)方法名称
  2. 对象方法引入 类名:: 实例方法名称
  3. 实例方法引入 new对象 对象实例::方法引入
  4. 构造函数引入 类名::new

需要遵循一个规范:

方法引入 方法参数列表、返回类型与函数接口参数列表与返回类型必须要保持一致。

静态方法引入#

/*
* 静态方法引入
* */
public class Test01 {
    public static void main(String[] args) {
        MyFunctionalInterface myFunctionalInterface = () -> {
            /*引入getStaticMethod方法*/
            Test01.getStaticMethod();
        };
        myFunctionalInterface.get();

        // 使用方法引入调用方法 必须满足:方法引入的方法必须和函数接口中的方法参数列表/返回值一定保持一致。
        MyFunctionalInterface messageInterface = Test01::getStaticMethod;
        messageInterface.get();
    }
    public static void getStaticMethod() {
        System.out.println("我是 getMethod");
    }
}

实例对象方法引入#

public class Test02 {
    public static void main(String[] args) {
        Test02 test02=new Test02();
        MyFunctionalInterface myFunctionalInterface = () -> {
            /*引入getStaticMethod方法*/
            test02.getStaticMethod();
        };
        myFunctionalInterface.get();

        // 精简版
        MyFunctionalInterface messageInterface = test02::getStaticMethod;
        messageInterface.get();


    }
    public  void getStaticMethod() {
        System.out.println("我是 getMethod2");
    }
}

构造函数引入#

    public static void main(String[] args) {
        UserInterface userInterface=new UserInterface() {
            @Override
            public UserEntity getUser() {
                return new UserEntity();
            }
        };

        //精简版
        UserInterface userInterface3=UserEntity::new;
        userInterface2.getUser();

    }

对象方法引入

public class Test04 {
    public static void main(String[] args) {
        Myservice myservice=new Myservice() {
            @Override
            public String get(Test04 test04) {
                return test04.objGet();
            }
        };

        Myservice myservice1=(Test04-> Test04.objGet());

        //精简版  传入Test04 返回string值
        Myservice myservice2=Test04::objGet;


        Function<String,Integer> function=new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        };
        //精简版
        Function<String,Integer> function2=String::length;
        System.out.println(function2.apply("dfdf"));

    }
@FunctionalInterface
public interface Myservice {
    String get(Test04 userEntity);
}

JDK8Optional#

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

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

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

判断参数是否为空#

ofNullable(可以传递一个空对象)

Of(不可以传递空对象)

    public static void main(String[] args) {
        String username=null;
        Integer a1 = 1;
        Optional<Integer> a = Optional.ofNullable(a1);
        System.out.println(a.isPresent());//true

        Optional<String> username1 = Optional.ofNullable(username);
        System.out.println(username1.isPresent());//false
    }

isPresent表示结果返回是否为空, true 不为空,返回 false 为空

参数为空可以设定默认值#

    public static void main(String[] args) {
        Integer a1 = null;
        Integer a = Optional.ofNullable(a1).orElse(10);
        System.out.println(a);//10
    }

参数实现过滤#

public static void main(String[] args) {
    Integer a1 = 16;
    Optional<Integer> a = Optional.ofNullable(a1);
    //判断是否等于16
    boolean present = a.filter(new Predicate<Integer>() {
        @Override
        public boolean test(Integer integer) {
            return integer.equals(16);
        }
    }).isPresent();
    System.out.println(present);//true

    boolean isPresent = a.filter(a2 -> a2==17).isPresent();
    System.out.println(isPresent);//false
}

与Lambda表达式结合使用,优化代码#

优化方案1#

    public static void main(String[] args) {
        // 优化前
        String name = "meite";
        if (name != null) {
            System.out.println(name);
        }
        //优化后
        Optional<String> name2 = Optional.ofNullable(name);
        // 当value 不为空时,则不会调用
        name2.ifPresent(s -> System.out.println(s));
        name2.ifPresent(System.out::print);
    }

优化方案2#

public class Test05 {
    private static UserEntity userEntity = null;

    public static void main(String[] args) {
        UserEntity userEntity = Test05.getOrder();
        System.out.println(userEntity);
    }
    public static UserEntity getOrder() {
        // 优化前
        if (userEntity == null) {
            return createOrder();
        }
        return userEntity;
         //优化1
        return Optional.ofNullable(Test05.userEntity).orElseGet(new Supplier<UserEntity>() {
            @Override
            public UserEntity get() {
                return createOrder();
            }
        });

        //优化2
        return Optional.ofNullable(Test05.userEntity).orElseGet(()-> {
           Test05.userEntity =createOrder();
           return Test05.userEntity;
        });

        //精简版
        return Optional.ofNullable(Test05.userEntity).orElseGet(() -> createOrder());
    }

    private static UserEntity createOrder() {
        return new UserEntity("ylc", 12);
    }
}

优化方案3#

public class Test06 {
    public static void main(String[] args) {

        String orderName = Test06.getOrderName();
        System.out.println(orderName);
    }
    public static String getOrderName() {
        // 优化前写法:
        UserEntity userEntity = new UserEntity("123456", 19);
        if (userEntity != null) {
            String userEntityName = userEntity.getName();
            if (userEntityName != null) {
                return userEntityName.toLowerCase();
            }
        }
        //优化后
        Optional<String> s1 = Optional.ofNullable(userEntity)
                .map((s) -> s.getName())
                .map((s) -> s.toLowerCase());

        return s1.get();
    }
}

原文链接:https://www.cnblogs.com/cg-ww/p/15426274.html

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java8新特性

    1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 中的默认方法与静态方法 6....

    用户1212940
  • Java8 新特性

    北京时间2018年9月26日,Oracle官方发布Java 11。既然版本都更新到11了,现在才来学8是不是太晚了?其实不是的,目前应该大部分都还是使用的Jav...

    贪挽懒月
  • Java8新特性

    1.HashMap 首先就是对 java 的 HashMap 进行了修改,以前是通过 hashCode 方法来判断他们的地址值是否一样 ,如果相同的话再使用 e...

    lwen
  • Java8新特性

    前言: Java 8 已经发布很久了,很多报道表明 Java 8 是一次重大的版本升级。在 Java Code Geeks 上已经有很多介绍 Java 8 新特...

    Dylan Liu
  • Java8新特性

    Jdk8提供了java.util.function包,提供了常用的函数式功能接口。

    牧晗
  • java8 新特性

    Java 8 Tutorial 接口的默认方法(Default Methods for Interfaces) Lambda表达式(Lambda expre...

    居士
  • Java8新特性

    Lambda表达式可以看成是匿名内部类,使用Lambda表达式时,接口必须是函数式接口

    shimeath
  • java8新特性

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    suveng
  • Java8 新特性

    Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以取代大部分的匿名内部类,可以写出更简洁...

    Java架构师必看
  • Java8新特性——Optional

    在开发中,我们常常需要对一个引用进行判空以防止空指针异常的出现。Java8引入了Optional类,为的就是优雅地处理判空等问题。现在也有很多类库在使用Opti...

    Happyjava
  • Java|Java8 新特性

    前言 Java8已经出现了很久了,但是呢,还是有很多人都还在习惯使用以前的来版本JDK,或者是以前老版本的编程方式。通过一段时间对Java8新特性的学习之后,自...

    算法与编程之美
  • Java8新特性实践

    神秘的寇先森
  • Java8新特性——StreamAPI(二)

    1. 收集器简介 收集器用来将经过筛选、映射的流进行最后的整理,可以使得最后的结果以不同的形式展现。 collect方法即为收集器,它接收Collector接...

    大闲人柴毛毛
  • Java8新特性——StreamAPI(一)

    1. 流的基本概念 1.1 什么是流? 流是Java8引入的全新概念,它用来处理集合中的数据,暂且可以把它理解为一种高级集合。 众所周知,集合操作非常麻烦,若...

    大闲人柴毛毛
  • java8新特性整理

    官方文档:http://docs.oracle.com/javase/specs/jls/se8/html/index.html

    pollyduan
  • java8新特性(二):StreamAPI

    Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是Stream API(java.util.stream.*)。 Stream 是J...

    周三不加班
  • Java8新特性之Stream

    本来以为Java8的新特性需要3篇文章才能写完的,但是发现其实Stream的接口并不想象的那么多,今天就可以完结啦!

    用户8902830
  • Java8新特性第3章

    Stream作为Java8的新特性之一,他与Java IO包中的InputStream和OutputStream完全不是一个概念。Java8中的Stream是对...

    企鹅号小编
  • java8新特性Lambda和Stream

    Java8出来已经4年,但还是有很多人用上了jdk8,但并没用到里面的新东西,那不就等于没用?jdk8有许多的新特性,详细可看下面脑图

    KEN DO EVERTHING

扫码关注云+社区

领取腾讯云代金券