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 {
@Override
public void run() {
System.out.println("多线程程序启动了");
}
}
~~~~~~~~~~~~~~~new Thread方式~~~~~~~~~~~~~~~~~~~~~~~~~~
MyRunnable my = new MyRunnable();
Thread t = new Thread(my);
t.start();
~~~~~~~~~~~~~~~匿名内部类方式~~~~~~~~~~~~~~~~~~~~~~~~~~
new Thread(new Runnable() {
@Override
public 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 {
@Override
public void eat() {
System.out.println("一天一苹果,医生远离我");
}
}
//测试类
public class EatableDemo {
public static void main(String[] args) {
//在主方法中调用useEatable方法
Eatable e = new EatableImpl();
useEatable(e);
//进化
//匿名内部类
useEatable(new Eatable() {
@Override
public 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:11
Stream流主要用于操作集合
*/
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);
统计集合中的元素个数:count
Long count = list.stream().mapToInt(Integer::parseInt).count();
}
}
把Stream流得到的结果统计到集合中:
集合对象.collect(Collectors.toXXX());