体验lambda表达式
@Test
public void lambdaTest01(){
// 老的写法
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Run 方法执行了");
}
};
runnable.run();
// 新的写法
Runnable runnable1 = ()->System.out.println("lambda run");
runnable1.run();
}
lambda 在写法上更加的间接,写的代码行数更少
lambda的语法格式:(形参1,形参2...形参n) -> 重写抽象方法的方法体
无参数,无返回值
@Test
public void lambdaTest02(){
Runnable runnable = () -> { System.out.println("runnable run"); };
runnable.run();
Runnable runnable1 = ()-> System.out.println("runnable run");
runnable1.run();
}
有参数,没有返回值
@Test
public void lambdaTest03(){
Consumer consumer = (monry) -> System.out.println("肯德基的价格是:"+monry);
consumer.accept(100);
Consumer consumer1 = (money) -> { System.out.println("汉堡的价格是:" + money); };
consumer1.accept(100);
Consumer consumer2 = (mv) -> { System.out.println("我爱看:" + mv); };
consumer2.accept("四驱兄弟");
}
有一个参数,小括号可以省略
@Test
public void lambdaTest04(){
Consumer consumer1 = money -> System.out.println("汉堡的价格是:" + money);
consumer1.accept(100);
}
有参数,有返回值
@Test
public void lambdaTest05(){
Comparator<Integer> comparator = (o1, o2) -> {return o1.compareTo(o2);};
int compare = comparator.compare(25, 20);
System.out.println(compare);
Comparator<Integer> comparator1 = (o1,o2) -> o1.compareTo(o2);
int compare1 = comparator1.compare(25, 20);
System.out.println(compare1);
}
认识函数式接口
一个接口里只有一个抽象方法,并且在这个抽象方法上标注FunctionalInterface注解的。
Java内置四大核心函数式接口
演示案例
@Test
public void lambdaTest06(){
//Consumer
Consumer consumer = (name -> {
System.out.println("我叫:" + name);
});
consumer.accept("牛某某");
//Supplier
Supplier supplier = () -> {return "You are Smart";};
Object o = supplier.get();
System.out.println(o);
//Function
Function<Integer,Double> function = (num1) -> {return Double.valueOf(num1); };
Double apply = function.apply(10);
System.out.println(apply);
//Predicate
Predicate<Integer> predicate = (number) -> {return number >= 20;};
boolean test = predicate.test(20);
System.out.println(test);
}
运行结果:
方法引用
实例::对象方法
Consumer 中的 void accept(T t)
PrintStream 中的 void println(T t)
@Test
public void lambdaTest07(){
Consumer<String> con1 = s -> System.out.println(s);
con1.accept("上海");
System.out.println("******************");
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("北京");
}
@Test
public void lambdaTest08(){
// Supplier T get();
// Employee int getAge()
Employee employee = new Employee();
employee.setAge(18);
Supplier<Integer> supplier = employee::getAge;
Integer age = supplier.get();
System.out.println(age);
//Consumer void accept(T t);
//Employee void setSalary(double salary)
Consumer<Double> consumer = employee::setSalary;
consumer.accept(100.00);
System.out.println(employee.getSalary());
}
类::静态方法
@Test
public void lambdaTest09(){
//lambda表达式的写法
Comparator<Integer> com = (t1,t2) -> Integer.compare(t1,t2);
System.out.println(com.compare(12, 21));
//方法引用的写法
Comparator<Integer> com1 = Integer::compare;
System.out.println(com1.compare(10, 20));
}
类::非静态方法
@Test
public void lambdaTest10(){
Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
System.out.println(com1.compare("abc", "def"));
//Comparator int compare(T o1, T o2);
//String中的 int o1.compareTo(o2)
Comparator<String> com2 = String::compareTo;
System.out.println(com2.compare("abc", "def"));
}
构造器引用
@Test
public void lambda11(){
//Supplier T get();
//Employee Employee()
System.out.println();
//lambda表达式写法
Supplier<Employee> sup = ()->new Employee();
System.out.println(sup.get());
//构造器引用的写法
Supplier<Employee> sup1 = Employee :: new;
System.out.println(sup1.get());
}
数组引用
@Test
public void lambda11(){
//lambda 表达式
Function<Integer,String[]> func1 = length -> new String[length];
String[] apply = func1.apply(5);
System.out.println(Arrays.toString(apply));
System.out.println("******************************************");
//数组引用的写法
Function<Integer,String[]> func2 = String[] :: new;
String[] apply1 = func2.apply(10);
System.out.println(Arrays.toString(apply1));
}
StreamAPI
Stream 的三个操作步骤
1- 创建 Stream
一个数据源(如:集合、数组),获取一个流
2- 中间操作
一个中间操作链,对数据源的数据进行处理
3- 终止操作(终端操作)
一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
Stream 实例化
package com.java.entity;
/**
* 其他的方法 请自行生成
*/
public class Employee {
private int id;
private String name;
private int age;
private double salary;
}
/**
* 提供用于测试的数据
*
* @author shkstart 邮箱:shkstart@126.com
*
*/
public class EmployeeData {
public static List<Employee> getEmployees(){
List<Employee> list = new ArrayList<>();
list.add(new Employee(1001, "马化腾", 34, 6000.38));
list.add(new Employee(1002, "马云", 12, 9876.12));
list.add(new Employee(1003, "刘强东", 33, 3000.82));
list.add(new Employee(1004, "雷军", 26, 7657.37));
list.add(new Employee(1005, "李彦宏", 65, 5555.32));
list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));
list.add(new Employee(1007, "任正非", 26, 4333.32));
list.add(new Employee(1008, "扎克伯格", 35, 2500.32));
list.add(new Employee(1003, "刘强东", 33, 3000.82));
return list;
}
}
实例化方式一:通过集合
// default Stream<E> stream() : 返回一个顺序流
// default Stream<E> parallelStream() : 返回一个并行流
List<Employee> employees = EmployeeData.getEmployees();
//返回一个顺序流
Stream<Employee> stream = employees.stream();
//返回一个并行流
Stream<Employee> parallelStream = employees.parallelStream();
实例化方式二:通过数组
//static <T> Stream<T> stream(T[] array): 返回一个流
@Test
public void streamTest1(){
int[] arr = new int[]{1,2,3,4,5,6};
IntStream stream = Arrays.stream(arr);
Employee e1 = new Employee(1001, "Tom");
Employee e2 = new Employee(1002, "lucy");
Employee[] arr1 = {e1, e2};
Stream<Employee> stream1 = Arrays.stream(arr1);
}
实例化方式三:通过Stream.of
// public static<T> Stream<T> of(T... values) : 返回一个流
@Test
public void streamTest2(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
}
创建无限流
//迭代
//public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
//生成
//public static<T> Stream<T> generate(Supplier<T> s)
@Test
public void streamTest3(){
//遍历前10个数
Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
//生成10个数
Stream.generate(Math::random).limit(10).forEach(System.out::println);
}
Stream的中间操作
筛选与切片
@Test
public void streamTest4(){
List<Employee> list = EmployeeData.getEmployees();
//filter
Stream<Employee> stream = list.stream();
stream.filter(e -> e.getSalary()>7000).forEach(System.out::println);
System.out.println();
//limit
list.stream().limit(3).forEach(System.out::println);
System.out.println();
//skip
list.stream().skip(4).forEach(System.out::println);
System.out.println();
//distinct
list.stream().distinct().forEach(System.out::println);
}
映射
@Test
public void streamTest5(){
//map
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
//小练习:获取员工姓名长度大于3的员工的姓名
List<Employee> employees = EmployeeData.getEmployees();
Stream<String> nameStream = employees.stream().map(Employee::getName);
nameStream.filter(name -> name.length()>3).forEach(System.out::println);
Stream<Stream<Character>> streamStream = list.stream().map(jdk8Test2Stream::fromStringStream);
streamStream.forEach(s -> {
s.forEach(System.out::println);
});
System.out.println("****************************************************************");
//flagMap
Stream<Character> characterStream = list.stream().flatMap(jdk8Test2Stream::fromStringStream);
characterStream.forEach(System.out::println);
}
public static Stream<Character> fromStringStream(String str){
ArrayList<Character> list = new ArrayList<>();
for (Character c:str.toCharArray()) {
list.add(c);
}
return list.stream();
}
| map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。 |
|---|---|
| mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 DoubleStream。 |
| mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 IntStream。 |
| mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 LongStream。 |
| flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流 |
| 方法 | 描述 |
|---|---|
| filter(Predicate p) | 接收 Lambda , 从流中排除某些元素 |
| distinct() | 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素 |
| limit(long maxSize) | 截断流,使其元素不超过给定数量 |
| skip(long n) | 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一 个空流。与 limit(n) 互补 |
排序
@Test
public void streamTest6(){
//sorted 自然排序
List<Integer> list = Arrays.asList(12, 34, 65, 34, 877, 0, -98, 7);
list.stream().sorted().forEach(System.out::println);
//sorted(Comparator com) 定制排序
List<Employee> employees = EmployeeData.getEmployees();
employees.stream().sorted((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge())).forEach(System.out::println);
}
Stream的终止操作
匹配和查找
| 方法 | 描述 |
|---|---|
| allMatch(Predicate p) | 检查是否匹配所有元素 |
| anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
| noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
| findFirst() | 返回第一个元素 |
| findAny() | 返回当前流中的任意元素 |
| count() | 返回流中元素总数 |
| max(Comparator c) | 返回流中最大值 |
| min(Comparator c) | 返回流中最小值 |
| forEach(Consumer c) | 内部迭代(使用 Collection 接口需要用户去做迭代, 称为外部迭代。相反,Stream API 使用内部迭 代——它帮你把迭代做了) |
@Test
public void streamTest7(){
List<Employee> employees = EmployeeData.getEmployees();
//allMatch
boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
System.out.println(allMatch);
//anyMatch
boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() > 10000);
System.out.println(anyMatch);
//noneMatch
boolean noneMatch = employees.stream().noneMatch(e -> e.getName().contains("雷"));
System.out.println(noneMatch);
//findFirst
Optional<Employee> findFirst = employees.stream().findFirst();
System.out.println(findFirst);
//findAny
Optional<Employee> findAny = employees.stream().findAny();
System.out.println(findAny);
//count
long count = employees.stream().count();
System.out.println(count);
//max
Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
Optional<Double> max = salaryStream.max(Double::compareTo);
System.out.println(max);
//min
Optional<Employee> employee = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(employee);
//forEach
employees.stream().forEach(System.out::println);
}
规约
| 方法 | 描述 |
|---|---|
| reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一 个值。返回 T |
| reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一 个值。返回 Optional |
@Test
public void streamTest8(){
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
//reduce
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum);
//reduce(BinaryOperator b)
List<Employee> employees = EmployeeData.getEmployees();
Stream<Double> doubleStream = employees.stream().map(Employee::getSalary);
Optional<Double> reduce = doubleStream.reduce((d1, d2) -> d1 + d2);
System.out.println(reduce);
//Optional<Double> sumMoney = doubleStream.reduce(Double::max);
//System.out.println(sumMoney);
}
收集
| 方法 | 规约 |
|---|---|
| collect(Collector c) | 将流转换为其他形式。接收一个 Collector 接口的实现,用于给Stream中元素做汇总 的方法 |
@Test
public void streamTest9(){
List<Employee> employees = EmployeeData.getEmployees();
List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
employeeList.forEach(System.out::println);
System.out.println();
Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
employeeSet.forEach(System.out::println);
}
Optional类
Optional类的相关方法
Option类的使用
创建两个新的实体类
public class Boy {
private Girl girl;
public Boy() {}
public Boy(Girl girl) {
this.girl = girl;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
@Override
public String toString() {
return "Boy{" +
"girl=" + girl +
'}';
}
}
public class Girl {
private String name;
public Girl(String name) {
this.name = name;
}
public Girl() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Girl{" +
"name='" + name + ''' +
'}';
}
}
@Test
public void optionTest1(){
Girl girl = new Girl();
Optional<Girl> girl1 = Optional.of(girl);
System.out.println(girl1);
}
@Test
public void optionalTest2(){
Girl girl = new Girl();
girl = null;
Optional<Girl> girl1 = Optional.ofNullable(girl);
System.out.println(girl1);
}
@Test
public void optionalTest3(){
Optional<Object> empty = Optional.empty();
System.out.println(empty);
}
Optional类的使用举例
//如何有效避免空指针
@Test
public void optionalTest4(){
Girl girl = new Girl();
girl = null;
Optional<Girl> optionalGirl = Optional.ofNullable(girl);
System.out.println(optionalGirl);
System.out.println("***************************");
/**
* orElse(T t)
* 如果optional内部封装的T是非空的,则返回内部的t
* 如果optional内部封装的T是空的,则返回orElse()方法中的参数
*/
Girl otherGirl = optionalGirl.orElse(new Girl("嗯哼"));
System.out.println(otherGirl);
}