1、接口中的新特性

JDK1.7以前:
抽象方法
常量
JDK1.8:
默认方法

  1. public default 返回值类型 方法的名称(参数列表){
  2. 方法体
  3. }
  4. ~~~~~~~~~~~~~~~~~接口~~~~~~~~~~~~~~~~~~~~~~~~~
  5. public interface LiveAble {
  6. public default void fly(){
  7. //一般的接口中的方法没有方法体的
  8. System.out.println("飞");
  9. }
  10. }
  11. ~~~~~~~~~~~~~~~~接口实现类~~~~~~~~~~~~~~~~~~~~
  12. public class Animal implements LiveAble {
  13. //不用写啥,因为是default修饰的默认方法,不是必须实现的,因为其有方法体,可以直接用
  14. }
  15. ~~~~~~~~~~~~~~~~测试类~~~~~~~~~~~~~~~~~~~~
  16. public class InterfaceDemo {
  17. public static void main(String[] args) {
  18. // 创建接口实现类对象
  19. Animal a = new Animal();
  20. // 调用默认方法
  21. a.fly();
  22. }
  23. }

静态方法

  1. public static 返回值类型 方法名称(参数列表){
  2. 方法体
  3. }
  4. ~~~~~~~~~~~~~~接口~~~~~~~~~~~~~~~~~
  5. public interface LiveAble {
  6. public default void fly(){
  7. System.out.println("飞~~~");
  8. }
  9. }
  10. ~~~~~~~~~~~~~~接口实现类~~~~~~~~~~~~~~~~~
  11. public class Animal implements LiveAble {
  12. // 无法重写静态方法
  13. }
  14. ~~~~~~~~~~~~~~测试类~~~~~~~~~~~~~~~~~~~
  15. public class InterfaceDemo {
  16. public static void main(String[] args) {
  17. // Animal.run();【错误】无法继承方法,也无法调用 LiveAble.run();
  18. // 使用的是哪个接口中的静态方法,所以只允许使用接口名.静态方法(参数列表) 使用
  19. 接口名.方法名(参数);
  20. }
  21. }

JDK1.9:
私有方法

  1. ~~~~~~~~~~~~~私有方法~~~~~~~~~~~~~~~~~~~
  2. public interface MyInterfacePrivateA {
  3. public default void methodDefault1() {
  4. System.out.println("默认方法1");
  5. methodCommon();
  6. }
  7. public default void methodDefault2() {
  8. System.out.println("默认方法2");
  9. methodCommon();
  10. }
  11. //意义是抽取核心代码到一个私有方法中供其他方法调用
  12. private void methodCommon() {
  13. System.out.println("AAA");
  14. System.out.println("BBB");
  15. System.out.println("CCC");
  16. }
  17. }
  18. ~~~~~~~~~~~~~静态私有方法~~~~~~~~~~~~~~~~~~~
  19. public interface MyInterfacePrivateB {
  20. public static void methodStatic1() {
  21. System.out.println("静态方法1");
  22. methodStaticCommon();
  23. }
  24. public static void methodStatic2() {
  25. System.out.println("静态方法2");
  26. methodStaticCommon();
  27. }
  28. //抽取核心代码(共性代码)到一个私有方法中供其他方法调用,减少代码,提高复用率,提高安全.
  29. private static void methodStaticCommon() {
  30. System.out.println("AAA");
  31. System.out.println("BBB");
  32. System.out.println("CCC");
  33. }
  34. }

Lambda表达式

Java8新有的新特性,使java代码具有函数式的编程风格,就是简化了代码,抽象化了

函数式思想:

尽量忽略面向对象思想,强调做什么,而不是以什么形式去做。‘

体验Lambda:

  1. ~~~~~~~~~~~~~线程类~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. public class MyRunnable implements Runnable {
  3. @Override
  4. public void run() {
  5. System.out.println("多线程程序启动了");
  6. }
  7. }
  8. ~~~~~~~~~~~~~~~new Thread方式~~~~~~~~~~~~~~~~~~~~~~~~~~
  9. MyRunnable my = new MyRunnable();
  10. Thread t = new Thread(my);
  11. t.start();
  12. ~~~~~~~~~~~~~~~匿名内部类方式~~~~~~~~~~~~~~~~~~~~~~~~~~
  13. new Thread(new Runnable() {
  14. @Override
  15. public void run() {
  16. System.out.println("多线程程序启动了");
  17. }
  18. }).start();
  19. ~~~~~~~~~~~~~~~Lambda方式~~~~~~~~~~~~~~~~~~~~~~~~~~
  20. new Thread( () -> {
  21. System.out.println("多线程程序启动了");
  22. } ).start();

Lambda标准格式:

(形式参数)->{代码块}
形式参数:如果有多个参数,之间用逗号隔开,没参数就空格就可
->:固定写法,代表指向动作
代码块:是我们要做的事情,也就是原来写方法的那个方法体内容

Lambda表达式练习:

  1. //接口
  2. public interface Eatable {
  3. void eat();
  4. }
  5. //实现类
  6. public class EatableImpl implements Eatable {
  7. @Override
  8. public void eat() {
  9. System.out.println("一天一苹果,医生远离我");
  10. }
  11. }
  12. //测试类
  13. public class EatableDemo {
  14. public static void main(String[] args) {
  15. //在主方法中调用useEatable方法
  16. Eatable e = new EatableImpl();
  17. useEatable(e);
  18. //进化
  19. //匿名内部类
  20. useEatable(new Eatable() {
  21. @Override
  22. public void eat() {
  23. System.out.println("一天一苹果,医生远离我");
  24. }
  25. });
  26. //再进化
  27. //Lambda表达式
  28. useEatable(() -> {System.out.println("一天一苹果,医生远离我");});
  29. }
  30. private static void useEatable(Eatable e) {
  31. e.eat();
  32. }
  33. }

大致分为:
抽象方法是无参无返回值:
方法实现类对象(( ) -> {方法体});
抽象方法是有参无返回值:
方法实现类对象((参数列表) -> {方法体});
抽象方法有参有返回值:
方法实现类对象((参数列表) -> {方法体 return 返回值;});

Lambda表达式省略规则:

参数类型可以省略
如果参数有且仅有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号,以及return关键字

Lambda表达式的注意事项

使用Lambda必须要有接口,且接口有且仅有一个抽象方法
必须有上下文环境,才能推导出Lambda对应的接口

Stream流

Stream流的作用主要是用来操作集合的

筛选:filter( )

集合对象.stream().filter(条件1 ).filter(条件2)….filter(条件n); //满足n个条件的剩下的数据

截取:limit(long n)

集合对象.stream( ).limit(n); //截取前n个数据

跳过:skip(long n)

集合对象.stream( ).skip(n); //跳过前三个后剩下的数据

合并:concat(A,B)

Stream.concat(A,B); //合并A和B为一个集合
Stream.concat(A,B).distinct( ); //把合并A和B后集合中的重复元素去除

排序:sorted( )

集合对象.stream().sorted(); //把集合中的数据按照自然顺序排序

  1. package com.smiledog.streamdemo;
  2. /*
  3. @ClassName StreamDemo
  4. @Author SmILeDog
  5. @Date 2021/5/13
  6. @Time 17:11
  7. Stream流主要用于操作集合
  8. */
  9. import java.util.ArrayList;
  10. import java.util.Collection;
  11. import java.util.stream.Stream;
  12. public class StreamDemo {
  13. public static void main(String[] args) {
  14. ArrayList<String> list = new ArrayList<>();
  15. list.add("张三");
  16. list.add("李四儿");
  17. list.add("王五");
  18. list.add("赵六儿");
  19. list.add("刘备");
  20. list.add("关羽");
  21. list.add("张飞");
  22. // 筛选:filter()方法 条件:姓张,名字长度小于三,打印
  23. list.stream().filter(s -> s.startsWith("刘")).filter(s -> s.length() < 3).forEach(s -> System.out.println(s));
  24. System.out.println("~~~~~~~~~~~~~~");
  25. //截取:limit(int i)方法 条件:截取前三个,打印
  26. list.stream().limit(3).forEach(s -> System.out.println(s));
  27. System.out.println("~~~~~~~~~~~~~~");
  28. //跳过:skip(int i)方法 条件:跳过前三个 然后截取三个,打印
  29. list.stream().skip(3).limit(3).forEach(s -> System.out.println(s));
  30. System.out.println("~~~~~~~~~~~~~~");
  31. //合并:concat(流1 , 流2)方法
  32. Stream<String> limitandskip = list.stream().skip(3).limit(3);//跳过前三个,然后截取三个
  33. Stream<String> limit = list.stream().limit(3); //截取前三个
  34. Stream<String> skip = list.stream().skip(3); //跳过前三个
  35. //Stream.concat(limit,skip).forEach(s -> System.out.println(s));
  36. Stream<String> concat1 = Stream.concat(limit, skip); //合并后两个
  37. //Stream.concat(limitandskip,concat1).forEach(s -> System.out.println(s));
  38. System.out.println("~~~~~~~~~~~~~~~~~~~");
  39. //去重:distinct()方法
  40. //合并第一个和后两个的和 ,去除重复的数据,然后打印
  41. Stream.concat(limitandskip, concat1).distinct().forEach(s -> System.out.println(s));
  42. }
  43. }

转换类型数据:map( );

集合对象.stream( ).mapToXXX(转换操作).操作;

  1. public class StreamDemo {
  2. public static void main(String[] args) {
  3. //创建一个集合,存储多个字符串元素
  4. ArrayList<String> list = new ArrayList<String>();
  5. list.add("10");
  6. list.add("20");
  7. list.add("30");
  8. list.add("40");
  9. list.add("50");
  10. //需求:将集合中的字符串数据转换为整数之后在控制台输出
  11. // list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
  12. // list.stream().map(Integer::parseInt).forEach(System.out::println);
  13. // list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
  14. //int sum() 返回此流中元素的总和
  15. int result = list.stream().mapToInt(Integer::parseInt).sum();
  16. System.out.println(result);
  17. 统计集合中的元素个数:count
  18. Long count = list.stream().mapToInt(Integer::parseInt).count();
  19. }
  20. }

把Stream流得到的结果统计到集合中:

  1. 集合对象.collect(Collectors.toXXX());