Java8
1、接口中可以定义默认方法并且有方法体,也可以定义静态方法。通过实现类调用
//Order.java
public interface Order {
void add();
default void get(){
System.out.println("get");
}
static void delete(){
System.out.println("delete");
}
}
//OrderImpl.java
public class OrderImpl implements Order{
@Override
public void add() {
System.out.println("add");
}
public static void main(String[] args) {
OrderImpl order = new OrderImpl();
//调用抽象方法
order.add();
//调用默认方法
order.get();
//调用静态方法
Order.delete();
}
}
2、接口中的方法不能像类一样直接new出来进行调用,但是可以通过匿名内部类来实现对接口中的方法进行调用。用lambda表达式更加简单
public class Test01 {
public static void main(String[] args) {
new Order() {
@Override
public void add() {
System.out.println("add");
}
}.add();
}
}
3、函数接口
(1)接口中只允许定义一个抽象方法
(2)一般用@FunctionalInterface修饰,这样的话当定义的抽象方法多余1个就会报错
(3)接口中可以定义普通方法(用default修饰)
(4)接口中可以定义object类中的方法
@FunctionalInterface
public interface MyFunctionalInterface {
void get();
default void delete(){
System.out.println("delete");
}
String toString();
}
4、lambda表达式
(1)用lambda表达式实现接口中方法的调用
(2)当方法体中有一条语句 不用写{}、不用写return
- 无参、无返回值
//AcanthopanaxInterface.java @FunctionalInterface public interface AcanthopanaxInterface { void get(); } //Test02.java public class Test02 { public static void main(String[] args) { //1、使用匿名内部类 new AcanthopanaxInterface() { @Override public void get() { System.out.println("get"); } }.get(); //2、使用lambda ((AcanthopanaxInterface)()-> System.out.println("get")).get(); } }
- 有参、有返回值
//ZhInterface.java @FunctionalInterface public interface ZhInterface { int add(int i,int j); } //Test03.java public class Test03 { public static void main(String[] args) { //使用匿名内部类 int add = new ZhInterface() { @Override public int add(int i, int j) { return i + j; } }.add(1, 2); System.out.println(add); //使用lambda表达式 int add1 = ((ZhInterface) (i, j) -> i + j).add(1, 2); System.out.println(add1); } }
5、实战
(1)foreach
public class ForEachTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
//使用匿名内部类
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//使用lambda表达式
list.forEach(s -> System.out.println(s));
}
}
(2)集合排序
//User.java
@Data
@AllArgsConstructor
public class User {
String name;
int age;
}
//SortTest.java
public class SortTest {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",3));
//1、匿名内部类排序
list.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o2.getAge()-o1.getAge();
}
});
list.forEach(user -> System.out.println(user));
//2、使用lambda表达式
list.sort((o1,o2)->o1.getAge()-o2.getAge());
list.forEach(user -> System.out.println(user));
}
}
(3)多线程
public class ThreadTest {
public static void main(String[] args) {
//使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"子线程");
}
}).start();
//使用lambda表达式
new Thread(()-> System.out.println(Thread.currentThread().getName()+"子线程")).start();
}
}
6、Stream
stream流可以非常精简的遍历集合,实现过滤、排序等
(1)通过stream把list转换为set
public class Stream01 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",3));
list.add(new User("王五",3));
list.stream().collect(Collectors.toSet()).forEach(user -> System.out.println(user));
}
}
/**
思考:把list转换为set后,数据还是重复的为什么?
因为user对象没有重写equals方法,比较的是对象的地址,王五这个对象是分别new的地址是不一样的,所以会重复(set集合底层依赖map集合实现防重复key map集合底层基于equals结合hashcode比较实现防重复)
补充知识点:
“==”和equals的区别:
(1) “==”是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值。
(2) equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重写之后比较的是对象的值。
*/
(2)通过stream把list转换为map
public class Stream02 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",3));
//1、使用匿名内部类
Map<String, User> userMap = list.stream().collect(Collectors.toMap(new Function<User, String>() {
@Override
public String apply(User user) {
return user.getName();
}
}, new Function<User, User>() {
@Override
public User apply(User user) {
return user;
}
}));
//2、使用lambda表达式
Map<String, User> userMap2 = list.stream().collect(Collectors.toMap(user -> user.getName(), user -> user));
}
}
(3)使用stream求和
public class Stream03 {
public static void main(String[] args) {
//使用匿名内部类
Integer sum1 = Stream.of(1, 2, 3, 4, 5).reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer a, Integer b) {
return a + b;
}
}).get();
//使用lambda表达式
Integer sum2 = Stream.of(1, 2, 3, 4, 5).reduce((a, b) -> a + b).get();
}
}
(4)使用stream求max和min
public class Stream04 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",19));
list.add(new User("老六",32));
list.add(new User("三七",2));
//使用匿名内部类 max
User user1 = list.stream().max(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
}).get();
//使用匿名内部类 min
User user2 = list.stream().min(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
}).get();
//使用lambda表达式 max
User user11 = list.stream().max((a, b) -> a.getAge() - b.getAge()).get();
//使用lambda表达式 min
User user22 = list.stream().min((a, b) -> a.getAge() - b.getAge()).get();
}
}
(5)stream匹配match
public class Stream05 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",19));
list.add(new User("老六",32));
list.add(new User("三七",2));
//只要有一个满足就是true
boolean flag = list.stream().anyMatch(new Predicate<User>() {
@Override
public boolean test(User user) {
return "张三".equals(user.getName());
}
});
//使用lambda表达式
list.stream().anyMatch(user -> "张三".equals(user.getName()));
//都要满足
boolean flag2 = list.stream().allMatch(new Predicate<User>() {
@Override
public boolean test(User user) {
return 40 > user.getAge();
}
});
//使用lambda表达式
list.stream().allMatch(User->40>User.getAge());
}
}
(6)stream过滤器filter
public class Stream06 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",19));
list.add(new User("老六",32));
list.add(new User("三七",2));
list.stream().filter(new Predicate<User>() {
@Override
public boolean test(User user) {
return user.getAge()>20;
}
}).forEach(user -> System.out.println(user));
//使用lambda表达式实现
list.stream().filter(user -> user.getAge()>20).forEach(user -> System.out.println(user));
}
}
(7)stream的limit和skip
public class Stream07 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",1));
list.add(new User("李四",2));
list.add(new User("王五",19));
list.add(new User("老六",32));
list.add(new User("三七",2));
list.stream().skip(2).limit(2).forEach(user -> System.out.println(user));
list.stream().limit(5).skip(2).forEach(user -> System.out.println(user));
}
}
(8)stream综合案例
筛选出成年并且和“张三”同名的人 按年龄从大到小 取top2
public class Stream08 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",19));
list.add(new User("张三",12));
list.add(new User("张三",21));
list.add(new User("张三",31));
list.add(new User("张三",32));
list.add(new User("张三",34));
list.add(new User("张三",4));
list.add(new User("张三",5));
list.add(new User("李四",2));
list.add(new User("王五",19));
list.add(new User("老六",32));
list.add(new User("三七",2));
list.stream().filter(user -> user.getAge()>18).filter(user -> "张三".equals(user.getName())).sorted((a,b)->b.getAge()-a.getAge()).limit(2).forEach(user -> System.out.println(user));
}
}
7、jdk8自带一些函数接口
消费型接口:
Conusmer
void accept(T t);
BiConusmer<T,U>
void accept(T t,U u);//增加一种入参类型
供给型接口
Supplier
void get();
函数型接口
Function<T ,R>
R apply(T t);
UnaryOperator
T apply(T t);//入参与返回值类型一致
BiFunction <T ,U,R>
R apply(T t,U u);//增加一个参数类型
BinaryOperator
T apply(T t1,T t2);//l两个相同类型入参与同类型返回值
ToIntFunction//限定返回int
ToLongFunction//限定返回long
ToDoubleFunction//限定返回double
IntFunction//限定入参int,返回泛型R
LongFunction//限定入参long,返回泛型R
DoubleFunction//限定入参double,返回泛型R
断言型接口
Predicate
boolean test(T t);
8、方法引入
结合lambda表达式让代码变得更加简洁
注意:方法引入 就是lambda表达式中直接引入的方法
必须遵循的规范:引入方法的参数列表以及返回类型必须要和函数接口的参数列表及返回类型保持一致
(1)静态方法引入 类名::(静态)方法名称
//MessageInterface.java
@FunctionalInterface
public interface MessageInterface {
void get(Integer a);
}
//Test04.java
public class Test04 {
public static void main(String[] args) {
//匿名内部类
new MessageInterface() {
@Override
public void get(Integer a) {
geta(a);
}
}.get(1);
//lambda表达式
MessageInterface me=(a)->Test04.geta(a);
me.get(1);
//方法引入
MessageInterface geta = Test04::geta;
geta.get(1);
}
public static void geta(Integer a){
System.out.println(a);
}
}
(2)对象方法引入 类名:: (实例)方法名称
(3)实例方法引入 对象实例:: 方法名称
//MessageInterface2.java
@FunctionalInterface
public interface MessageInterface2 {
void get();
}
//Test05.java
public class Test05 {
public static void main(String[] args) {
Test05 test05 = new Test05();
//使用lambda表达式
MessageInterface2 messageInterface2 = () -> test05.staGet();
messageInterface2.get();
//使用方法引入
MessageInterface2 messageInterface21=test05::staGet;
messageInterface21.get();
}
public void staGet() {
System.out.println("hhh");
}
}
(4)构造函数引入 类名:: new
9、java8新特性Optional
(1)ofNullable(可以传递一个空对象),而Of(不可以传递空对象)
(2)参数为空可以设定默认值
public class Test06 {
public static void main(String[] args) {
Integer a=null;
System.out.println(Optional.ofNullable(a).orElse(10));
}
}
(3)判空优化(ifPresent 如果前面的判断不为空)
public class Test07 {
public static void main(String[] args) {
String aaa="a";
if (null!=aaa){
System.out.println(aaa);
}
//优化
Optional.ofNullable(aaa).ifPresent(s -> System.out.println(aaa));
}
}
(4)判空优化
public class Test08 {
static Integer b=null;
public static void main(String[] args) {
Integer a=null;
// if (null==a){
// getb();
// System.out.println(b);
// }
//优化
Integer b = Optional.ofNullable(a).orElseGet(() -> {
getb();
return Test08.b;
});
System.out.println(b);
}
private static void getb() {
b=111;
}
}
(5)判空优化
public class Test09 {
public static void main(String[] args) {
User user = new User("ZhdooO", 111);
if (null!=user){
System.out.println(user.getName().toLowerCase());
}
//优化
System.out.println(Optional.ofNullable(user).map(u -> u.getName()).map(name->name.toLowerCase()).get());
}
}