接口中默认方法修饰为普通方法
在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表达式 依赖于函数接口
- 在接口中只能够允许有一个抽象方法
- 在函数接口中定义object类中方法
- 使用默认或者静态方法
- @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表达式能够让代码变得更加精简
- 静态方法引入: 类名::(静态)方法名称
- 对象方法引入 类名:: 实例方法名称
- 实例方法引入 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<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(); } }