1. 接口特性
- default 默认方法 由实现类继承
public class TestInterface {
public static void main(String[] args) {
Formula formula = new Formula() {
@Override
public void method3() {
System.out.println("hello3");
}
};
formula.method1();// 默认方法
Formula.method2();// 静态调用
formula.method3();// 重写方法
}
interface Formula{
default void method1(){
System.out.println("hello1");
}
static void method2(){
System.out.println("hello2");
}
public void method3();
}
}
2. lambda表达式
2. 1 lambda的基本使用
public class TestLambda {
interface Printer{
void print(String var);
}
public void printSomething(String var, Printer printer){
printer.print(var);
}
public static void main(String[] args) {
TestLambda lambda = new TestLambda();
// 匿名内部类
Printer printer = new Printer(){
@Override
public void print(String var) {
System.out.println(var);
}
};
// Lambda 参数-> 方法体
printer=(String var)->{
System.out.println(var);
};
// 简化1 可以省略类型
printer=(var)->{
System.out.println(var);
};
// 简化2 单个形参省略形参括号()
printer=var->{
System.out.println(var);
};
// 简化3 方法单条语句省略{}
printer=var-> System.out.println(var);
lambda.printSomething("hello Lambda",printer);
}
}
2. 2 函数式接口
只定义一个抽象方法的的接口。
Runnable runnable=()-> System.out.println("hello");
- 异常、Lambda,还有函数式接口又是怎么回事呢?
请注意,任何函数式接口都不允许抛出受检异常(checked exception)。如果你需要Lambda 表达式来抛出异常,有两种办法:定义一个自己的函数式接口,并声明受检异常,或者把Lambda 包在一个try/catch块中。
- Consumer 只进不出
public static void main(String[] args) {
// 定义 函数
MyConsumer myConsumer = str-> System.out.println("MyConsumer<<<<<"+str);
// 调用 函数
myConsumer.accept("hello world");
}
interface MyConsumer extends Consumer<String>{
}
- Function<T,R> 进进出出
interface MyFunction extends Function<Integer,String>{
}
MyFunction myFunction=integer -> integer.toString();
- Predicate 返回判断值
MyPredicate myPredicate=phone->phone.equals("SAMSUNG");
interface MyPredicate extends Predicate<String>{
}
3. Stream API
- Stream流程图
3. 1 能转化为流的类型
public class TestStream {
public static void main(String[] args) throws IOException {
List<String> list = Arrays.asList("Lisi", "Wangwu", "Jihad", "Lilei");
String[] arr={"Lisi", "Wangwu", "Jihad", "Lilei"};
// 将数组转换为stream流
Stream<String> nameStraeam = Stream.of(arr);
// 将文件转换为流
Path path = Paths.get("file.txt");
Stream<String> stream = Files.lines(path);
// 将集合转换为流 {过滤出以L开头的名字全部大写进行排序 获取集合}
List<String> names = list.stream().
filter(name -> name.startsWith("L")).
map(name -> name.toUpperCase()).sorted().collect(Collectors.toList());
names.forEach(System.out::println);
}
}
3. 2 谓词逻辑 filter
public static void main(String[] args) {
Employee e1 =new Employee(1,23,"M","Rick","Beethovan");
Employee e2 =new Employee(2,13,"F","Martina","Hengis");
Employee e3 =new Employee(3,43,"M","Ricky","Martin");
Employee e4 =new Employee(4,26,"M","Jon","Feezor");
Employee e5 =new Employee(5,19,"F","Cristine","Roy");
Employee e6 =new Employee(6,15,"M","David","Gussin");
Employee e7 =new Employee(7,68,"F","Melissa","Lowman");
Employee e8 =new Employee(8,79,"M","Alex","Singh");
Employee e9 =new Employee(9,15,"F","Neetu","Singh");
Employee e10 =new Employee(10,45,"M","Naveen","Jain");
List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
// filter -- 查询年龄>70 的男性
List<Employee> list = employees.stream().filter(
e -> e.getAge() > 70 && "M".equals(e.getGender())
).collect(Collectors.toList());
// 提高复用性 or|| and&& negate!
List<Employee> list2 = employees.stream().filter(
Employee.ageGreatThan70.and(Employee.genderIsM)
).collect(Collectors.toList());
System.out.println(list2);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private Integer age;
private String gender;
private String firstName;
private String lastName;
// 实现Predicate的匿名内部类
public static Predicate<Employee> ageGreatThan70=new Predicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getAge()>70;
}
};
public static Predicate<Employee> genderIsM= e->"M".equals(e.getGender());
}
3. 3 映射 map
- 基本使用
public static void main(String[] args) {
// 将集合中的字符串全部转化为大写
// 原始方法
List<String> phones = Arrays.asList("apple", "sasmung", "oppo", "vivo");
ArrayList<String> phoneUpCase = new ArrayList<>();
for (String phone : phones) {
phoneUpCase.add(phone.toUpperCase());
}
System.out.println(phoneUpCase);
// lambda 使用map映射
List<String> collect = phones.stream().map(str -> str.toUpperCase()).collect(Collectors.toList());
System.out.println(collect);
}
- 复用性提高
public static void main(String[] args) {
Employee e1 =new Employee(1,23,"M","Rick","Beethovan");
Employee e2 =new Employee(2,13,"F","Martina","Hengis");
Employee e3 =new Employee(3,43,"M","Ricky","Martin");
Employee e4 =new Employee(4,26,"M","Jon","Feezor");
Employee e5 =new Employee(5,19,"F","Cristine","Roy");
Employee e6 =new Employee(6,15,"M","David","Gussin");
Employee e7 =new Employee(7,68,"F","Melissa","Lowman");
Employee e8 =new Employee(8,79,"M","Alex","Singh");
Employee e9 =new Employee(9,15,"F","Neetu","Singh");
Employee e10 =new Employee(10,45,"M","Naveen","Jain");
List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
List<Employee> collect = employees.stream().map(Employee.ageGrowthOne).collect(Collectors.toList());
System.out.println(collect);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private Integer age;
private String gender;
private String firstName;
private String lastName;
public static Function<Employee,Employee> ageGrowthOne=e->{
e.setAge(e.getAge()+1);
e.setGender("M".equals(e.getGender())?"male":"female");
return e;
};
}
3. 4 原子映射flatMap
public class TestFlatMap {
public static void main(String[] args) {
List<String> list = Arrays.asList("hello", "world");
// 并不会将数组对象拆分 1对1
list.stream().map(
str -> str.split("")
).forEach(System.out::println);
// 使用flatMap 拆分为单个对象 1对多
list.stream().flatMap(str-> Stream.of(str.split("")))
.forEach(System.out::println);
}
}
- 输出结果
3. 5 有状态操作
- limit(n) 取前n个
- skip(n) 去后(allNum - n)个
- distinct() 去重
- sorted()排序/可定制排序
public static void main(String[] args) {
List<String> phones = Arrays.asList("apple","apple", "sasmung", "oppo", "vivo");
phones.stream().limit(2).forEach(str-> System.out.print(str+" "));
System.out.println("<<<<<<<<<<<<<");
phones.stream().skip(2).forEach(str-> System.out.print(str+" "));
System.out.println("<<<<<<<<<<<<<");
phones.stream().sorted(String::compareTo).forEach(str-> System.out.print(str+" "));
System.out.println("<<<<<<<<<<<<<");
phones.stream().distinct().forEach(str-> System.out.print(str+" "));
}
- parallel() 并行操作
有状态操作
使用并行操作会影响数据的正确性,并行适用于无状态操作。
- 并行操作处理类型难易
3. 6 匹配规则
- anyMatch 任一符合
Employee e1 = new Employee(1, 23, "M", "Rick", "Beethovan");
Employee e2 = new Employee(2, 13, "F", "Martina", "Hengis");
Employee e3 = new Employee(3, 43, "M", "Ricky", "Martin");
Employee e4 = new Employee(4, 26, "M", "Jon", "Feezor");
Employee e5 = new Employee(5, 19, "F", "Cristine", "Roy");
Employee e6 = new Employee(6, 15, "M", "David", "Gussin");
Employee e7 = new Employee(7, 68, "F", "Melissa", "Lowman");
Employee e8 = new Employee(8, 79, "M", "Alex", "Singh");
Employee e9 = new Employee(9, 15, "F", "Neetu", "Singh");
Employee e10 = new Employee(10, 45, "M", "Naveen", "Jain");
List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
boolean ageGreathan70 = employees.stream().anyMatch(e -> e.getAge() > 70);// 判断员工年龄是否含有大于70岁的
System.out.println(ageGreathan70);
- allMatch 全部符合
boolean allAgeGreatThan12=employees.stream().allMatch(e->e.getAge()>12);// 判断所有员工年龄都在12岁以上
3. 7 终止操作
- reduce
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer total = list.stream().reduce(0, (subtotal, element) -> subtotal += element);
System.out.println(total);
total = list.stream().reduce(0, Integer::sum);
System.out.println(total);
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
employees.stream().map(Employee::getAge).reduce(0,Integer::sum);
}
- count() 返回元素总数
- max/min(Comparator c) 返回流中最大/小值
- forEach(Consumer c) 内部迭代
4. 方法引用
- 类名:: 静态方法名
- 类名:: 实例方法名
- 调用静态方法 形参列表和使用的方法形参列表相同。
- 调用实例方法 形参列表第一个参数作为调用者,其余为函数的形参列表
public static void main(String[] args) {
Employee employee=new Employee(9,15,"F","Neetu","Singh");
A a = new A();
a.print(e->e.getAge());
a.print(Employee::getAge);
}
static class A{
void print(Function<? extends Employee,? extends Integer> function){
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private Integer age;
private String gender;
private String firstName;
private String lastName;
public Integer sum(Employee e1){
return this.getAge()+e1.getAge();
}
public Integer sum(Employee e1,Employee e2){// 这两个sum方法 使用方法引用会冲突
return e2.getAge()+e1.getAge();
}
}
public static void main(String[] args) {
Employee employee=new Employee(9,15,"F","Neetu","Singh");
B b = new B();
b.sum(Employee::sum);
}