1、接口中的新特性
JDK1.7以前:
抽象方法
常量
JDK1.8:
默认方法
public default 返回值类型 方法的名称(参数列表){方法体}~~~~~~~~~~~~~~~~~接口~~~~~~~~~~~~~~~~~~~~~~~~~public interface LiveAble {public default void fly(){//一般的接口中的方法没有方法体的System.out.println("飞");}}~~~~~~~~~~~~~~~~接口实现类~~~~~~~~~~~~~~~~~~~~public class Animal implements LiveAble {//不用写啥,因为是default修饰的默认方法,不是必须实现的,因为其有方法体,可以直接用}~~~~~~~~~~~~~~~~测试类~~~~~~~~~~~~~~~~~~~~public class InterfaceDemo {public static void main(String[] args) {// 创建接口实现类对象Animal a = new Animal();// 调用默认方法a.fly();}}
静态方法
public static 返回值类型 方法名称(参数列表){方法体}~~~~~~~~~~~~~~接口~~~~~~~~~~~~~~~~~public interface LiveAble {public default void fly(){System.out.println("飞~~~");}}~~~~~~~~~~~~~~接口实现类~~~~~~~~~~~~~~~~~public class Animal implements LiveAble {// 无法重写静态方法}~~~~~~~~~~~~~~测试类~~~~~~~~~~~~~~~~~~~public class InterfaceDemo {public static void main(String[] args) {// Animal.run();【错误】无法继承方法,也无法调用 LiveAble.run();// 使用的是哪个接口中的静态方法,所以只允许使用接口名.静态方法(参数列表) 使用接口名.方法名(参数);}}
JDK1.9:
私有方法
~~~~~~~~~~~~~私有方法~~~~~~~~~~~~~~~~~~~public interface MyInterfacePrivateA {public default void methodDefault1() {System.out.println("默认方法1");methodCommon();}public default void methodDefault2() {System.out.println("默认方法2");methodCommon();}//意义是抽取核心代码到一个私有方法中供其他方法调用private void methodCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}~~~~~~~~~~~~~静态私有方法~~~~~~~~~~~~~~~~~~~public interface MyInterfacePrivateB {public static void methodStatic1() {System.out.println("静态方法1");methodStaticCommon();}public static void methodStatic2() {System.out.println("静态方法2");methodStaticCommon();}//抽取核心代码(共性代码)到一个私有方法中供其他方法调用,减少代码,提高复用率,提高安全.private static void methodStaticCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}
Lambda表达式
Java8新有的新特性,使java代码具有函数式的编程风格,就是简化了代码,抽象化了
函数式思想:
体验Lambda:
~~~~~~~~~~~~~线程类~~~~~~~~~~~~~~~~~~~~~~~~~~public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("多线程程序启动了");}}~~~~~~~~~~~~~~~new Thread方式~~~~~~~~~~~~~~~~~~~~~~~~~~MyRunnable my = new MyRunnable();Thread t = new Thread(my);t.start();~~~~~~~~~~~~~~~匿名内部类方式~~~~~~~~~~~~~~~~~~~~~~~~~~new Thread(new Runnable() {@Overridepublic void run() {System.out.println("多线程程序启动了");}}).start();~~~~~~~~~~~~~~~Lambda方式~~~~~~~~~~~~~~~~~~~~~~~~~~new Thread( () -> {System.out.println("多线程程序启动了");} ).start();
Lambda标准格式:
(形式参数)->{代码块}
形式参数:如果有多个参数,之间用逗号隔开,没参数就空格就可
->:固定写法,代表指向动作
代码块:是我们要做的事情,也就是原来写方法的那个方法体内容
Lambda表达式练习:
//接口public interface Eatable {void eat();}//实现类public class EatableImpl implements Eatable {@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}}//测试类public class EatableDemo {public static void main(String[] args) {//在主方法中调用useEatable方法Eatable e = new EatableImpl();useEatable(e);//进化//匿名内部类useEatable(new Eatable() {@Overridepublic void eat() {System.out.println("一天一苹果,医生远离我");}});//再进化//Lambda表达式useEatable(() -> {System.out.println("一天一苹果,医生远离我");});}private static void useEatable(Eatable e) {e.eat();}}
大致分为:
抽象方法是无参无返回值:
方法实现类对象(( ) -> {方法体});
抽象方法是有参无返回值:
方法实现类对象((参数列表) -> {方法体});
抽象方法有参有返回值:
方法实现类对象((参数列表) -> {方法体 return 返回值;});
Lambda表达式省略规则:
参数类型可以省略
如果参数有且仅有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号,以及return关键字
Lambda表达式的注意事项
使用Lambda必须要有接口,且接口有且仅有一个抽象方法
必须有上下文环境,才能推导出Lambda对应的接口
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(); //把集合中的数据按照自然顺序排序
package com.smiledog.streamdemo;/*@ClassName StreamDemo@Author SmILeDog@Date 2021/5/13@Time 17:11Stream流主要用于操作集合*/import java.util.ArrayList;import java.util.Collection;import java.util.stream.Stream;public class StreamDemo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("张三");list.add("李四儿");list.add("王五");list.add("赵六儿");list.add("刘备");list.add("关羽");list.add("张飞");// 筛选:filter()方法 条件:姓张,名字长度小于三,打印list.stream().filter(s -> s.startsWith("刘")).filter(s -> s.length() < 3).forEach(s -> System.out.println(s));System.out.println("~~~~~~~~~~~~~~");//截取:limit(int i)方法 条件:截取前三个,打印list.stream().limit(3).forEach(s -> System.out.println(s));System.out.println("~~~~~~~~~~~~~~");//跳过:skip(int i)方法 条件:跳过前三个 然后截取三个,打印list.stream().skip(3).limit(3).forEach(s -> System.out.println(s));System.out.println("~~~~~~~~~~~~~~");//合并:concat(流1 , 流2)方法Stream<String> limitandskip = list.stream().skip(3).limit(3);//跳过前三个,然后截取三个Stream<String> limit = list.stream().limit(3); //截取前三个Stream<String> skip = list.stream().skip(3); //跳过前三个//Stream.concat(limit,skip).forEach(s -> System.out.println(s));Stream<String> concat1 = Stream.concat(limit, skip); //合并后两个//Stream.concat(limitandskip,concat1).forEach(s -> System.out.println(s));System.out.println("~~~~~~~~~~~~~~~~~~~");//去重:distinct()方法//合并第一个和后两个的和 ,去除重复的数据,然后打印Stream.concat(limitandskip, concat1).distinct().forEach(s -> System.out.println(s));}}
转换类型数据:map( );
集合对象.stream( ).mapToXXX(转换操作).操作;
public class StreamDemo {public static void main(String[] args) {//创建一个集合,存储多个字符串元素ArrayList<String> list = new ArrayList<String>();list.add("10");list.add("20");list.add("30");list.add("40");list.add("50");//需求:将集合中的字符串数据转换为整数之后在控制台输出// list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);// list.stream().map(Integer::parseInt).forEach(System.out::println);// list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);//int sum() 返回此流中元素的总和int result = list.stream().mapToInt(Integer::parseInt).sum();System.out.println(result);统计集合中的元素个数:countLong count = list.stream().mapToInt(Integer::parseInt).count();}}
把Stream流得到的结果统计到集合中:
集合对象.collect(Collectors.toXXX());
