接口
jdk8之前
-
接口中可以定义变量和方法
-
变量必须是public、static、final的
-
方法必须是public、abstract的,需要子类实现
-
且这些修饰符都是默认的
jdk8之后
-
方法可以有使用static或default修饰,可以有自己的方法体,且不需要子类强制实现
-
子类可以重写默认方法覆盖父类的默认方法
优缺点
之前:
好处:面向抽象而不是面向具体编程
缺陷:需要修改接口时,需要修改所有实现该接口的实现类
之后:引入默认方法
好处:解决接口的修改与现有的实现不兼容的问题
举例说明
/**
* @Author lian-chen
* @Date 2021/7/6 8:57
*/
public class Java8InterfaceTest {
public static void main(String[] args) {
Vehicle vehicle = new Car();
vehicle.print();
vehicle.run();
System.out.println("===============================");
FourWheeler fourWheeler = new Car();
fourWheeler.print();
}
}
interface Vehicle {
/**
* 接口变量:默认修饰符 public static final
*/
public static final int age = 18;
String name = "Vehicle";
/**
* 接口默认方法
*/
default void print() {
System.out.println("我是一辆车! 名字:"+name+" 年龄:"+age);
}
/**
* 接口静态方法
*/
static void blowHorn() {
System.out.println("按喇叭!!!");
}
/**
* 接口抽象方法
* 默认修饰符:public abstract
*/
public abstract void run();
}
interface FourWheeler {
/**
* 接口默认方法
*/
default void print() {
System.out.println("我是一辆四轮车!");
}
}
class Car implements Vehicle, FourWheeler {
/**
* 重写父类默认方法
*/
@Override
public void print() {
/**
* 实现多个接口相同的默认方法,super调用实现
*/
Vehicle.super.print();
FourWheeler.super.print();
/**
* 静态方法调用
*/
Vehicle.blowHorn();
System.out.println("我是一辆汽车!");
}
/**
* 实现父类接口方法
*/
@Override
public void run() {
System.out.println("实现跑起来。。。。");
}
}
我是一辆车! 名字:Vehicle 年龄:18
我是一辆四轮车!
按喇叭!!!
我是一辆汽车!
实现跑起来。。。。
===============================
我是一辆车! 名字:Vehicle 年龄:18
我是一辆四轮车!
按喇叭!!!
我是一辆汽车!
Lambda
-
java是不支持函数式编程的,将函数作为参数的形式传递
-
优缺点
好处:简化匿名内部类的调用
方法引入,代码变得更简洁
函数接口
-
接口中只能够允许一个抽象方法
-
在函数接口中定义object类中的方法
-
可以定义默认或者静态方法
-
@FunctionalInterface修饰函数接口
package com.ruoyi.web.controller.api;
/**
* @Author lian-chen
* @Date 2021/7/6 8:57
*/
public class Java8LamdbaTest {
public static void main(String[] args) {
/**
* 传统语法:将一个匿名内部类作为参数进行传递
* 我们实现了Runnable接口,并将其作为参数传递给Thread类
*/
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
});
thread.run();
/**
* Lamdba形式:能够接收Lambda表达式的参数类型,是一个只包含一个方法的接口,这种接口称之为 函数接口
*/
Thread thread1 = new Thread(() -> System.out.println("Hello1"));
thread1.run();
/**
* 使用自定义函数接口
*/
func(new FunctionInterface() {
@Override
public void test() {
System.out.println("自定义函数实现");
}
});
func(() -> {
System.out.println("自定义函数实现1");
});
FunctionInterface functionInterface = () -> {
System.out.println("自定义函数实现");
};
functionInterface.test();
((FunctionInterface) () -> System.out.println("自定义函数实现")).test();
/**
* 传统实现调用
*/
new FunctionHasParamInterface() {
@Override
public void test(int param) {
System.out.println(param);
}
}.test(8);
/**
* lambad表达式实现函数接口
*/
FunctionHasParamInterface functionHasParamInterface = (param) -> {
System.out.println(param);
};
functionHasParamInterface.test(8);
/**
* 简化代码: 强转
* 方法体中只有一条语句时可以省略{}
*/
((FunctionHasParamInterface) param -> System.out.println(param)).test(8);
new FunctionHasMoreParamInterface() {
@Override
public void test(int param1, int param2) {
System.out.println(param1 + "-" + param2);
}
}.test(1, 5);
FunctionHasMoreParamInterface functionHasMoreParamInterface = (param1, param2) -> {
System.out.println(param1 + "-" + param2);
};
functionHasMoreParamInterface.test(1, 5);
((FunctionHasMoreParamInterface) (param1, param2) -> System.out.println(param1 + "-" + param2)).test(1, 5);
/**
* 带返回值的
*/
int test1 = new FunctionHasParamAndHasReturnInterface(){
@Override
public int test(int param) {
return param * 2;
}
}.test(5);
int tes2 =((FunctionHasParamAndHasReturnInterface)(param)->{
return param * 2;
}).test(5);
/**
* 带返回值的且方法体中只有一行语句 可以省略{}和return
*/
int test3 = ((FunctionHasParamAndHasReturnInterface) (param) -> param * 2).test(5);
}
private static void func(FunctionInterface functionInterface) {
functionInterface.test();
}
}
/**
* 自定义函数接口
*/
@FunctionalInterface
interface FunctionInterface {
void test();
/**
* 注解提示不允许
*/
// void test2();
/**
* 可以定义父类object中的方法
*
* @return
*/
@Override
String toString();
/**
* 可以定义 默认和静态方法
*/
default void add() {
System.out.println("add");
}
static void del() {
System.out.println("del");
}
}
/**
* 自定义带参数的函数接口
*/
@FunctionalInterface
interface FunctionHasParamInterface {
/**
* 带参数形式
*
* @param param
*/
void test(int param);
}
@FunctionalInterface
interface FunctionHasMoreParamInterface {
/**
* 多参形式
*
* @param param1
* @param param2
*/
void test(int param1, int param2);
}
/**
* 自定义带参数且有返回值的函数接口
*/
@FunctionalInterface
interface FunctionHasParamAndHasReturnInterface {
/**
* 带参数形式
* 有返回值
* @param param
* @return
*/
int test(int param);
}
方法引入
-
結合Lamdba,使方法简洁
1.匿名内部类使用
2.Lamdba调用匿名内部类
3.方法引入
规范
-
方法参数列表、返回类型与函数接口参数列表与返回类型必须要保持一致
静态方法引入
-
类名::(静态)方法名称
public class Test {
public static void main(String[] args) {
// 在Lamdba表达式中方法体直接引入方法
MessageInterface messageInterface = (a) -> {
Test.staticGet(a);
};
messageInterface.get(2);
// 方法引入 实际上就是我们Lamdba表达式中方法体中直接引入方法
MessageInterface messageInterface2 = (a) -> Test.staticGet(a);
messageInterface2.get(2);
// 方法引入写法
MessageInterface messageInterface3 = Test::staticGet;
messageInterface3.get(2);
// 参数列表和返回类型必须和函数接口方法一致
MessageInterface2 messageInterface4 = Test::staticGet2;
messageInterface4.get(2, 3);
}
public static void staticGet(Integer a) {
System.out.println("staticGet:" + a);
}
//这种情况 可以不一致
public static String staticGet2(Integer a, Integer b) {
System.out.println("staticGet2:" + a + "-" + b);
return "111";
}
}
@FunctionalInterface
public interface MessageInterface {
void get(Integer param);
}
@FunctionalInterface
public interface MessageInterface2 {
void get(Integer param, Integer param2);
}
对象方法引入
-
类名::实例方法引入
public class Test {
public static void main(String[] args) {
// 使用匿名内部类的形式
MessageInterface messageInterface = new MessageInterface() {
@Override
public String getMessage(Test test) {
return test.objGet();
}
};
System.out.println(messageInterface.getMessage(new Test()));
// 使用lamdba
MessageInterface messageInterface2 = (test)-> test.objGet();
System.out.println(messageInterface2.getMessage(new Test()));
// 使用方法引入
MessageInterface messageInterface3 = Test::objGet;
System.out.println(messageInterface3.getMessage(new Test()));
}
public String objGet() {
return "hello lian-chen";
}
}
@FunctionalInterface
public interface MessageInterface {
String getMessage(Test test);
}
hello lian-chen
hello lian-chen
hello lian-chen
实例方法引入
-
new 对象 对象实例::方法引入
public class Test {
public static void main(String[] args) {
Test test = new Test();
MessageInterface messageInterface = () -> test.objGet();
System.out.println(messageInterface.getMessage());
// 对象方法引入
MessageInterface messageInterface2 = test::objGet;
System.out.println(messageInterface2.getMessage());
}
public String objGet() {
return "hello lian-chen";
}
}
@FunctionalInterface
public interface MessageInterface {
String getMessage();
}
hello lian-chen
hello lian-chen
构造函数引入
-
类名::new
public class Test {
public static void main(String[] args) {
MessageInterface messageInterface = () -> new MessageEntity();
System.out.println(messageInterface.getMessage());
// 构造方法引入
MessageInterface messageInterface2 = MessageEntity::new;
System.out.println(messageInterface2.getMessage());
}
public String objGet() {
return "hello lian-chen";
}
}
@FunctionalInterface
public interface MessageInterface {
MessageEntity getMessage();
}
static class MessageEntity {
private String messageId;
private String messageName;
public MessageEntity() {
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public String getMessageName() {
return messageName;
}
public void setMessageName(String messageName) {
this.messageName = messageName;
}
@Override
public String toString() {
return "MessageEntity{" +
"messageId='" + messageId + '\'' +
", messageName='" + messageName + '\'' +
'}';
}
}\
jdk自带函数式接口
-
package java.util.function;
public class Test {
public static void main(String[] args) {
Function<String, Integer> strFunction = (str) -> {
return str.length();
};
System.out.println(strFunction.apply("lian-chen"));
// 使用方法引入
Function<String, Integer> function2 = String::length;
System.out.println(function2.apply("lian-chen"));
}
}
9
9
消费型
供给型
函数型
断言型
Stream流
-
方便精简的形式遍历集合,实现过滤,排序等操作
中间操作
map
filter
distinct
sorted
limit
终止操作
forEach
collect
min,max
allMatch
例子
forEach
collect
public class User{
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) &&
Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan",18));
userList.add(new User("lisi",12));
userList.add(new User("lisi",12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
userList.add(wangwu);
userList.forEach(item->{
System.out.println(item);
});
System.out.println("去重==========");
/**
* 默认比较两个对象的内存地址是否相等, 需要重写equals和hashCode方法
* Set集合底层依赖于map集合实现防重复key,map集合底层基于equals比较防止重复
*/
Set<User> userSet = userList.stream().collect(Collectors.toSet());
userSet.forEach(System.out::println);
}
# 没有重写equals和hashcode
User{name='zhangsan', age=18}
User{name='lisi', age=12}
User{name='lisi', age=12}
User{name='wangwu', age=14}
User{name='wangwu', age=14}
去重==========
User{name='lisi', age=12}
User{name='lisi', age=12}
User{name='wangwu', age=14}
User{name='zhangsan', age=18}
# 重写equals和hashcode
User{name='zhangsan', age=18}
User{name='lisi', age=12}
User{name='lisi', age=12}
User{name='wangwu', age=14}
User{name='wangwu', age=14}
去重==========
User{name='wangwu', age=14}
User{name='zhangsan', age=18}
User{name='lisi', age=12}
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
// 注意相同的key值无法转换
// userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
// userList.add(wangwu);
userList.add(wangwu);
// List2Map
Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getName, item -> item));
userMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}
lisi:User{name='lisi', age=12}
zhangsan:User{name='zhangsan', age=18}
wangwu:User{name='wangwu', age=14}
reduce
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
Optional<Integer> reduce = Stream.of(10, 20, 30, 10).reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
});
System.out.println(reduce.get());
Optional<Integer> reduce1 = Stream.of(10, 20, 30, 10).reduce((a, b) -> a + b);
System.out.println(reduce1.get());
Optional<User> sum = userList.stream().reduce(new BinaryOperator<User>() {
@Override
public User apply(User user, User user2) {
User sum = new User("sum", user.getAge() + user2.age);
return sum;
}
});
System.out.println(sum.get().getAge());
Optional<User> sum1 = userList.stream().reduce((u1, u2) -> new User("sum", u1.getAge() + u2.getAge()));
System.out.println(sum1.get().getAge());
}
70
70
44
44
max
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
Optional<User> max = userList.stream().max(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
});
Optional<User> max1 = userList.stream().max(((o1, o2) -> o1.getAge() - o2.getAge()));
System.out.println(max.get());
System.out.println(max1.get());
Optional<User> min = userList.stream().min(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
});
Optional<User> mi2 = userList.stream().min((Comparator.comparingInt(User::getAge)));
System.out.println(min.get());
System.out.println(mi2.get());
}
User{name='zhangsan', age=18}
User{name='zhangsan', age=18}
User{name='lisi', age=12}
User{name='lisi', age=12}
match
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
boolean b = userList.stream().anyMatch(item -> {
return "wangwu".equals(item.getName());
});
System.out.println(b);
boolean a = userList.stream().anyMatch(item -> {
return "aa".equals(item.getName());
});
System.out.println(a);
boolean c = userList.stream().allMatch(item -> {
return "wangwu".equals(item.getName());
});
System.out.println(c);
boolean d = userList.stream().allMatch(item -> "wangwu".equals(item.getName()));
System.out.println(d);
}
true
false
false
false
filter
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
userList.stream().filter(new Predicate<User>() {
@Override
public boolean test(User user) {
return user.getAge() > 14;
}
}).forEach(System.out::println);
System.out.println("=========");
userList.stream().filter(item->"wangwu".equals(item.getName())&&item.getAge()>12).forEach(System.out::println);
}
User{name='zhangsan', age=18}
=========
User{name='wangwu', age=14}
limit
skip
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
userList.stream().limit(2).forEach(System.out::println);
System.out.println("=========");
userList.stream().skip(1).limit(2).forEach(System.out::println);
System.out.println("=========");
userList.stream().limit(2).skip(1).forEach(System.out::println);
}
User{name='zhangsan', age=18}
User{name='lisi', age=12}
=========
User{name='lisi', age=12}
User{name='wangwu', age=14}
=========
User{name='lisi', age=12}
sorted
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("zhangsan", 18));
userList.add(new User("lisi", 12));
User wangwu = new User("wangwu", 14);
userList.add(wangwu);
userList.stream().sorted(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge()-o2.getAge();
}
}).forEach(System.out::println);
System.out.println("===============");
userList.stream().sorted(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o2.getAge()-o1.getAge();
}
}).forEach(System.out::println);
System.out.println("===========");
userList.stream().sorted((o1, o2) -> o2.getAge()- o1.getAge()).forEach(System.out::println);
}
User{name='lisi', age=12}
User{name='wangwu', age=14}
User{name='zhangsan', age=18}
===============
User{name='zhangsan', age=18}
User{name='wangwu', age=14}
User{name='lisi', age=12}
===========
User{name='zhangsan', age=18}
User{name='wangwu', age=14}
User{name='lisi', age=12}
并行流
-
使用多线程处理,拆分处理
public static void main(String[] args) {
Instant start0 = Instant.now();
long sum = 0;
for (long i = 0; i <= 5000000000000000L; i++) {
sum += i;
}
System.out.println(sum);
Instant end0 = Instant.now();
System.out.println("耗时:" + Duration.between(start0, end0).toMillis());
System.out.println("==========");
Instant start = Instant.now();
LongStream longStream = LongStream.rangeClosed(0, 5000000000000000L);
OptionalLong result = longStream.parallel().reduce(new LongBinaryOperator() {
@Override
public long applyAsLong(long left, long right) {
return left + right;
}
});
System.out.println(result.getAsLong());
Instant end = Instant.now();
System.out.println("耗时:" + Duration.between(start, end).toMillis());
}
Optional
-
校验对象是否为空处理业务
ofNullable
of
isPresent
orElse
filter
public class Test {
public static void main(String[] args) {
String name = null;
Optional optional = Optional.ofNullable(name);
// System.out.println(optional.get());
/**
* get()的时候报错 ofNullable 允许传入空值
* Exception in thread "main" java.util.NoSuchElementException: No value present
* at java.util.Optional.get(Optional.java:135)
* at com.ruoyi.web.controller.api.ApiCommonController$Test.main(ApiCommonController.java:43)
*/
String username = "lian-chen";
Optional optional2 = Optional.ofNullable(username);
System.out.println(optional2.get());//lian-chen
// Optional<String> name1 = Optional.of(name);
/**
* of 不允许传入空值
* Exception in thread "main" java.lang.NullPointerException
* at java.util.Objects.requireNonNull(Objects.java:203)
* at java.util.Optional.<init>(Optional.java:96)
* at java.util.Optional.of(Optional.java:108)
* at com.ruoyi.web.controller.api.ApiCommonController$Test.main(ApiCommonController.java:55)
*/
boolean present1 = optional.isPresent();
System.out.println(present1);//false
boolean present2 = optional2.isPresent();
System.out.println(present2);//true
/**
* isPresent 判断传入的值是否不为空 true 表示不为空 false 表示为空
*/
// 设置默认值
String s = Optional.ofNullable(name).orElse("lian-chen");
System.out.println(s);//lian-chen
// 参数过滤
boolean present = Optional.ofNullable(name).filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return "lian-chen".equals(s);
}
}).isPresent();
System.out.println(present);//false
}
}
ifPresent
public static void main(String[] args) {
// 使用
String username = "lian-chen";
// 一般写法
// if (username!=null){
// System.out.println(username);
// }
Optional<String> username1 = Optional.ofNullable(username);
// isPresent 写法
// boolean present1 = username1.isPresent();
// if (present1){
// System.out.println(username);
// }
// ifPresent 写法
username1.ifPresent(System.out::println);
}
orElseGet
rivate static String name = null;
public static void main(String[] args) {
System.out.println(getName());
System.out.println(name);
System.out.println(getName2());
System.out.println(name);
}
public static String getName() {
return Optional.ofNullable(name).orElse(createName());
}
public static String getName2() {
return Optional.ofNullable(name).orElseGet(new Supplier<String>() {
@Override
public String get() {
name = createName();
return name;
}
});
}
public static String createName(){
return "lian-chen";
}
lian-chen
null
lian-chen
lian-chen
static class Test {
private static String name = null;
public static void main(String[] args) {
System.out.println(getName());
System.out.println(name);
System.out.println(getName4());
System.out.println(name);
}
public static String getName() {
return Optional.ofNullable(name).orElse(createName());
}
public static String getName2() {
return Optional.ofNullable(name).orElseGet(new Supplier<String>() {
@Override
public String get() {
name = createName();
return name;
}
});
}
//lamdba
public static String getName3() {
return Optional.ofNullable(name).orElseGet(() -> {
name = createName();
return name;
});
}
// 方法引入
public static String getName4() {
return Optional.ofNullable(name).orElseGet(Test::orElseGet);
}
public static String createName() {
return "lian-chen";
}
public static String orElseGet() {
name = createName();
return name;
}
}
lian-chen
null
lian-chen
lian-chen