Java8新特性

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

}
image-20211018202027296

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表达式 依赖于函数接口

在接口中只能够允许有一个抽象方法

在函数接口中定义object类中方法

使用默认或者静态方法

@FunctionalInterface 表示该接口为函数接口

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

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

@FunctionalInterface
public interface MyFunctionalInterface {

void  get();

default void add() {

}
String toString();

}
常见例如Runnable接口

image-20211018221019469

方法调用

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 arrayList=new ArrayList<>();
    arrayList.add("111");
    arrayList.add("222");
    arrayList.add("333");

// arrayList.forEach(new Consumer() {
// @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 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() {
        @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程序员的生产力,让程序员写出高效率、干净、简洁的代码

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

img

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

Stream创建方式#
parallelStream为并行流采用多线程执行

Stream采用单线程执行

parallelStream效率比Stream要高

Stream将list转换为set#
public static void main(String[] args) {

    ArrayList 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 stream=userEntities.stream();
    Set 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 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 stream=userEntities.stream();
    Map collect = stream.collect(Collectors.toMap(new Function() {
        @Override
        public String apply(UserEntity o) {
            return o.getName();
        }
    }, new Function() {
        @Override
        public UserEntity apply(UserEntity usrentity) {
            return usrentity;
        }
    }));

    //精简版
    collect.forEach(new BiConsumer() {
        @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 integerStream=Stream.of(5,6,7,8);
    Optional reduce = integerStream.reduce(new BinaryOperator() {
        @Override
        public Integer apply(Integer integer, Integer integer2) {
            return integer + integer2;
        }
    });
    System.out.println(reduce);

    ArrayList 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 sum=userEntities.stream().reduce(new BinaryOperator() {
        @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 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 stream=userEntities.stream();
    Optional min = stream.min(new Comparator() {
        @Override
        public int compare(UserEntity o1, UserEntity o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    System.out.println(min.get());

    //简化版
    Optional 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 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 stream=userEntities.stream();

    boolean b = stream.anyMatch(new Predicate() {
        @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 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 stream=userEntities.stream();
    stream.forEach((userEntity -> System.out.println(userEntity)));
}

Stream filter过滤器#

public static void main(String[] args) {
    ArrayList 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 stream=userEntities.stream();
    stream.filter(new Predicate() {
        @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 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 stream = userEntities.stream();
    stream.skip(2).limit(2).forEach((userEntity -> System.out.println(userEntity)));
}

stream 综合案例#
public static void main(String[] args) {

    ArrayList 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 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表达式能够让代码变得更加精简

静态方法引入: 类名::(静态)方法名称

对象方法引入 类名:: 实例方法名称

实例方法引入 new对象 对象实例::方法引入

构造函数引入 类名::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 function=new Function() {
        @Override
        public Integer apply(String s) {
            return s.length();
        }
    };
    //精简版
    Function 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 a = Optional.ofNullable(a1);
    System.out.println(a.isPresent());//true

    Optional 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 a = Optional.ofNullable(a1);
//判断是否等于16
boolean present = a.filter(new Predicate() {
    @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 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() {
        @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 s1 = Optional.ofNullable(userEntity)
            .map((s) -> s.getName())
            .map((s) -> s.toLowerCase());

    return s1.get();
}

}

你可能感兴趣的:(java)