33JDK1.8新特性(Lambda表达式Stream流)
Posted shawnyue-08
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了33JDK1.8新特性(Lambda表达式Stream流)相关的知识,希望对你有一定的参考价值。
目录
Lambda表达式
package org.westos.demo;
import java.util.ArrayList;
import java.util.Comparator;
/**
* @author lwj
* @date 2020/6/20 9:00
*/
public class MyTest {
public static void main(String[] args) {
/*
Lambda表达式:JDK1.8引入的一种语法,这种语法可以对匿名内部类进行简写,
*/
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(121);
arrayList.add(131);
arrayList.add(111);
arrayList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//最核心的代码
return Integer.compare(o1, o2);
}
});
System.out.println(arrayList);
//[111, 121, 131]
}
}
自定义接口和Lambda表达式
package org.westos.demo;
/**
* @author lwj
* @date 2020/6/20 9:11
*/
public interface MyInterface {
/**
* 抽象方法
* @param s 形参1
* @param i 形参2
*/
void show(String s, Integer i);
}
package org.westos.demo;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author lwj
* @date 2020/6/20 9:06
*/
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>(Arrays.asList(100, 200, 50));
/*
Lambda表达式的语法:
JDK1.8引入了一个箭头符号,将Lambda表达式分为左右两部分,左边是接口中抽象方法的形参列表,带括号;右边是抽象方法的具体实现逻辑
*/
arrayList.sort((o1, o2) -> Integer.compare(o1, o2));
//如果我要得到一个MyInterface接口的子类对象,我们可以使用匿名内部类--->Lambda表达式
MyInterface impl = (String s, Integer i) -> {
System.out.println(s + i);
};
//参数列表的参数类型可以省略
MyInterface impl2 = (s, i) -> {
System.out.println(s + i);
};
//如果实现逻辑只有一行代码,可以省略{},但是如果有多行实现,那么不能省略{}
MyInterface impl3 = (s, i) -> System.out.println(s + i);
}
}
带返回值的情况
package org.westos.demo;
/**
* @author lwj
* @date 2020/6/20 9:24
*/
public class MyTest3 {
public static void main(String[] args) {
//采用匿名内部类
MyInterface2 myInterface2 = new MyInterface2() {
@Override
public int add(int a, int b) {
return a + b;
}
};
//使用Lambda表达式简写
MyInterface2 impl = (a, b) -> a + b;
//你对方法的实现逻辑只有一行,那么{}和return关键字都可以省略
//但是方法的实现逻辑有多行时,那么{}和return都不能省略
//Lambda表达式不会有.class字节码,而匿名内部类的方式会有.class
}
}
interface MyInterface2 {
/**
* 加
* @param a a
* @param b b
* @return a + b
*/
int add(int a, int b);
}
参数个数只有一个
package org.westos.demo;
/**
* @author lwj
* @date 2020/6/20 9:30
*/
public class MyTest4 {
public static void main(String[] args) {
MyInterface3 myInterface3 = new MyInterface3() {
@Override
public int square(int num) {
return num * num;
}
};
MyInterface3 impl = n -> n * n;
//当参数列表只有一个参数时,()可以省略
//当方法的实现逻辑只有一行,那么return关键字和{}都可以省略
}
}
interface MyInterface3 {
/**
* square
* @param num num
* @return num
*/
int square(int num);
}
Lambda表达式作为参数传递
package org.westos.demo2;
import java.util.Arrays;
import java.util.Comparator;
/**
* @author lwj
* @date 2020/6/20 9:54
*/
public class MyTest {
public static void main(String[] args) {
Integer[] array = {12, 9, 2};
/*Arrays.sort(array, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});*/
Arrays.sort(array, (o1, o2) -> o1 - o2);
System.out.println(Arrays.toString(array));
//[2, 9, 12]
}
}
Lambda表达式注意事项
package org.westos.demo2;
/**
* @author lwj
* @date 2020/6/20 10:03
*/
public class MyTest2 {
public static void main(String[] args) {
/*
Lambda表达式的注意事项:
1、Lambda表达式需要函数式接口的支持;
2、函数式接口:接口中只有一个方法;
3、@FunctionalInterface注解可以检测一个接口是不是函数式接口
4、如果接口中有多个抽象方法,那么不能使用Lambda表达式,只能使用匿名内部类
*/
}
}
@FunctionalInterface
interface MyInterface {
void show();
}
JDK1.8提供的函数式接口
主要在java.util.function
包下。
Consumer<T>
消费型接口,怎么消费由抽象方法的实现逻辑决定,有参数,但是没有返回值。
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
package org.westos.demo3;
import java.util.function.Consumer;
/**
* @author lwj
* @date 2020/6/20 10:13
*/
public class MyTest {
public static void main(String[] args) {
consumerString(t -> System.out.println(t.toUpperCase()));
}
public static void consumerString(Consumer<String> consumer) {
consumer.accept("Hello");
//HELLO
}
}
Supplier<T>
供给型接口,返回什么由抽象方法的实现逻辑决定,没有参数,但是有参数。
@FunctionalInterface
public interface Supplier<T> {
T get();
}
package org.westos.demo3;
import java.util.function.Supplier;
/**
* @author lwj
* @date 2020/6/20 10:42
*/
public class MyTest2 {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = " World";
Supplier<String> supplier = () -> str1 + str2;
System.out.println(supplier.get());
}
}
Predicate<T>
断言型接口,判断参数是否符合抽象方法的实现逻辑,有参数,返回值类型为boolean。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
package org.westos.demo3;
import java.util.function.Predicate;
/**
* @author lwj
* @date 2020/6/20 10:47
*/
public class MyTest3 {
public static void main(String[] args) {
Predicate<String> predicate = t -> t.length() > 5;
boolean b = testMethod(predicate);
System.out.println(b);
//false
}
public static boolean testMethod(Predicate<String> predicate) {
return predicate.test("Hello");
}
}
Function<T, R>
函数型接口,y = k * x,接收一个参数,经过抽象方法的逻辑处理,转换为另一种输出,有参数,有返回值。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
package org.westos.demo3;
import java.util.function.Function;
/**
* @author lwj
* @date 2020/6/20 11:05
*/
public class MyTest4 {
public static void main(String[] args) {
Function<String, Integer> function = Integer::parseInt;
//public static int parseInt(String s) 类名::静态方法 方法引用
method(function);
}
public static void method(Function<String, Integer> function) {
Integer apply = function.apply("100");
System.out.println(apply);
//100
}
}
方法引用
对Lambda表达式的进一步简写。
对象名::实例方法
package org.westos.demo4;
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* 方法引用一:对象::实例方法
* @author lwj
* @date 2020/6/20 10:19
*/
public class MyTest {
public static void main(String[] args) {
Consumer<String> consumer = t -> System.out.println(t);
consumer.accept("Hello");
//Hello
//方法引用
Consumer<String> stringConsumer = System.out::println;
/*
当抽象方法的实现逻辑已经有实现了,并且抽象方法的参数列表、返回值和已有(println)方法的参数列表、返回值相同,就可以使用方法引用
*/
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(100);
arrayList.forEach(System.out::println);
//forEach方法的参数是一个Consumer接口,public void forEach(Consumer<? super E> action)
//对象::方法名
}
}
类名::静态方法名
package org.westos.demo4;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 方法引用二:类名::静态方法
* @author lwj
* @date 2020/6/20 10:37
*/
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(100);
arrayList.add(50);
//Collections.sort(arrayList, (o1, o2) -> Integer.compare(o1, o2));
//Comparator接口 int compare(T o1, T o2),这时Integer.compare()方法,两个参数,返回int类型
//Comparator接口的形参列表、返回值和Integer类的compare方法的形参列表、返回值相同,所以可以使用方法引用
Comparator<Integer> comparator = Integer::compareTo;
Collections.sort(arrayList, comparator);
//类名::静态方法名
}
}
类名::实例方法名
package org.westos.demo4;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 方法引用三:类名::实例方法
* @author lwj
* @date 2020/6/20 10:52
*/
public class MyTest3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Hello");
arrayList.add("World");
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
//匿名内部类
//Collections.sort(arrayList, comparator);
Collections.sort(arrayList, String::compareTo);
//类名::实例方法
//int compare(T o1, T o2) ---> o1.compareTo(o2) 一个参数作为调用者,另一个参数作为被调用者时(或者第二个参数为空参),可以使用方法
//引用的第三种情况:类名::实例方法
}
}
构造器引用
package org.westos.demo5;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author lwj
* @date 2020/6/20 11:15
*/
public class MyTest {
public static void main(String[] args) {
/*
构造器引用:抽象方法的形参列表和构造器的形参列表相同
*/
//Supplier接口 T get() 返回一个对象
Supplier<MyClass> supplier = () -> new MyClass();
System.out.println(supplier.get());
//MyClass{s=‘null‘}
//将Lambda表达式转换为构造器引用
Supplier<MyClass> supplier1 = MyClass::new;
System.out.println(supplier1.get());
//MyClass{s=‘null‘}
Function<String, MyClass> function = s -> new MyClass(s);
MyClass myClass = function.apply("哈哈");
System.out.println(myClass);
//MyClass{s=‘哈哈‘}
Function<String, MyClass> function1 = MyClass::new;
MyClass myClass1 = function1.apply("嘿嘿");
System.out.println(myClass1);
//MyClass{s=‘嘿嘿‘}
}
}
class MyClass {
private String s;
public MyClass() {}
public MyClass(String s) {
this.s = s;
}
@Override
public String toString() {
return "MyClass{" +
"s=‘" + s + ‘‘‘ +
‘}‘;
}
}
两个参数的构造器
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
package org.westos.demo5;
import java.util.function.BiFunction;
/**
* @author lwj
* @date 2020/6/20 11:43
*/
public class MyTest2 {
public static void main(String[] args) {
BiFunction<String, Integer, Student> biFunction = Student::new;
Student student = biFunction.apply("张三", 23);
System.out.println(student);
//Student{name=‘张三‘, age=23}
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name=‘" + name + ‘‘‘ +
", age=" + age +
‘}‘;
}
}
Stream流
IO流操作的是文件,本质是字节数据的流动;
Stream流操作的是集合或者数组中的元素;
Stream流的出现,是为了我们更加方便的对集合中的元素进行操作(增删改查)。
获取流
package org.westos.demo;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* @author lwj
* @date 2020/6/20 13:30
*/
public class MyTest {
public static void main(String[] args) {
/*
我们要使用Stream流,得分三个阶段
1、获取Stream流;
2、中间环节的操作;
3、终止操作。
*/
/*
获取Stream流的几种方式
首先有一个容器;
方式一:通过集合中的方法stream()获取一个Stream流;
方式二:通过数组工具类Arrays.stream(T[])获取一个Stream流;
方式三:通过Stream类的静态方法Stream.of(T... t) 可变参数
方式四:获取无限流:
方式五:获取无限流;
*/
//方式一
List<Integer> list = Arrays.asList(20, 30, 40, 50);
Stream<Integer> stream = list.stream();
//流stream已经和集合关联,不会影响原先的集合
//方式二
Integer[] array = new Integer[]{10, 20, 30, 40};
Stream<Integer> stream1 = Arrays.stream(array);
//方式三
Stream<Integer> stream2 = Stream.of(60, 70, 80, 90);
//方式四
/*Stream<Integer> iterate = Stream.iterate(1, new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer integer) {
return integer + 1;
}
});*/
Stream<Integer> iterate = Stream.iterate(1, o -> o + 1);
//中间操作
Stream<Integer> limit = iterate.limit(5);
//终止操作
limit.forEach(System.out::println);
/*
1
2
3
4
5
*/
//方式五
Stream<Double> generate = Stream.generate(Math::random);
//generate(Supplier s) T get()
Stream<Double> limit1 = generate.limit(10);
limit1.forEach(System.out::println);
/*
0.5893316149903014
0.49657385857263114
0.5512757866500287
0.743934027848006
0.6722335733681098
0.9386635944230624
0.6644677410898912
0.3603432292811649
0.4797300332900708
0.23612726353592983
*/
}
}
中间操作
package org.westos.demo;
import java.util.Objects;
public class Employee {
private int id;
private String name;
private int age;
private double salary;
private Status status;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public Employee(int id, String name, int age, double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String show() {
return "测试方法引用!";
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status
+ "]";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return id == employee.id &&
age == employee.age &&
Double.compare(employee.salary, salary) == 0 &&
Objects.equals(name, employee.name) &&
status == employee.status;
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, salary, status);
}
public enum Status {
FREE,
BUSY,
VOCATION;
}
}
filter(Predicate<T> t) 和 distinct()
package org.westos.demo;
import java.util.Arrays;
import java.util.List;
/**
* @author lwj
* @date 2020/6/20 14:10
*/
public class MyTest2 {
public static void main(String[] args) {
/*
Stream流的中间环节的操作,不会对原有的集合容器有任何改变
*/
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//过滤出工资大于6000的员工
list.stream().filter(o -> o.getSalary() > 6000).forEach(System.out::println);
/*
Employee [id=102, name=李四, age=59, salary=6666.66, status=null]
Employee [id=101, name=张三, age=18, salary=9999.99, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
*/
System.out.println("-------------");
//过滤出姓赵的员工
list.stream().filter(o -> o.getName().startsWith("赵")).forEach(System.out::println);
/*
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
*/
System.out.println("-------------");
//过滤工资大于6000的员工,去除集合中的重复元素
list.stream().filter(o -> o.getSalary() > 6000).distinct().forEach(System.out::println);
/*
Employee [id=102, name=李四, age=59, salary=6666.66, status=null]
Employee [id=101, name=张三, age=18, salary=9999.99, status=null]
Employee [id=104, name=赵六, age=8, salary=7777.77, status=null]
*/
}
}
limit(long maxSize) 和 skip(long n)
package org.westos.demo2;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* limit 、 skip
* @author lwj
* @date 2020/6/20 14:54
*/
public class MyTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(10, 20, 30, 40, 50);
list.stream().filter(o -> o > 10).limit(2).forEach(System.out::println);
//返回大于10的元素,并且limit(long maxSize) 截断流,只要前2个
//20
//30
System.out.println("--------------");
list.stream().filter(o -> o > 10).skip(2).forEach(System.out::println);
//返回大于10的元素,并且跳过前2个,返回后面的元素
//40
//50
System.out.println("-------------");
//注意:终止操作不执行,中间环节不会执行
List<Integer> list1 = Arrays.asList(10, 20, 30);
Stream<Integer> integerStream = list1.stream().filter(o -> {
System.out.println("中间环节执行了");
return o > 10;
});
//没有输出,只有有终止操作,中间环节才会执行
integerStream.forEach(System.out::println);
/*
中间环节执行了
中间环节执行了
20
中间环节执行了
30
*/
}
}
map(Function<T, R> f) 和 flatMap()
package org.westos.demo2;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
/**
* map
* @author lwj
* @date 2020/6/20 15:28
*/
public class MyTest2 {
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//map(e -> e.getName()) String getName() --- R apply(T t) 第一个参数为调用者 类名::实例方法
list.stream().map(Employee::getName).distinct().forEach(System.out::println);
/*
李四
张三
王五
赵六
田七
*/
}
}
package org.westos.demo2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* @author lwj
* @date 2020/6/20 15:34
*/
public class MyTest3 {
public static void main(String[] args) {
List<String> strings = Arrays.asList("aaa", "bbb", "ccc");
strings.stream().map(String::toUpperCase).forEach(System.out::println);
//集合元素转大写
//String toUpperCase() --- R apply(T t) 第一个参数为调用者 类名::实例方法
/*
AAA
BBB
CCC
*/
System.out.println("------------------");
Stream<Stream<Character>> streamStream = strings.stream().map(o -> {
ArrayList<Character> characters = new ArrayList<>();
for (char c : o.toCharArray()) {
characters.add(c);
}
return characters.stream();
});
streamStream.forEach(t -> {
t.forEach(System.out::println);
});
/*
a
a
a
b
b
b
c
c
c
*/
System.out.println("-----------------");
//用flatMap(Function f)
Stream<Character> characterStream = strings.stream().flatMap(o -> {
ArrayList<Character> characters = new ArrayList<>();
for (char c : o.toCharArray()) {
characters.add(c);
}
return characters.stream();
});
//关键在于返回流的类型
characterStream.forEach(System.out::println);
/*
a
a
a
b
b
b
c
c
c
*/
}
}
mapToInt
package org.westos.demo2;
import java.util.Arrays;
import java.util.List;
/**
* @author lwj
* @date 2020/6/20 15:57
*/
public class MyTest4 {
public static void main(String[] args) {
List<String> list = Arrays.asList("100", "200", "300", "400");
list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//mapToInt(ToIntFunction t) 类名::静态方法
/*
100
200
300
400
*/
}
}
@FunctionalInterface
public interface ToIntFunction<T> {
int applyAsInt(T value);
}
sorted(Comparator<T> c)
package org.westos.demo2;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* @author lwj
* @date 2020/6/20 16:01
*/
public class MyTest5 {
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//按照员工的年龄大小排序
//自然排序:要求元素实现Comparable接口 sorted() 空参
//比较器排序:自定义排序规则
Stream<Employee> sorted = list.stream().sorted((o1, o2) -> Integer.compare(o1.getAge(), o2.getAge()));
sorted.forEach(System.out::println);
}
}
终止操作
查找和匹配
Predicate断言型接口
boolean test(T t);
package org.westos.demo3;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.List;
/**
* @author lwj
* @date 2020/6/20 16:06
*/
public class MyTest {
public static void main(String[] args) {
//终止操作:当我们执行完了中间环节,就想要执行终止操作来得到结果
//终止操作最常用的是打印,forEach(Consumer<T> c) void accept(T e)
//有的时候不只是要打印,还要获取
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
boolean allMatch = list.stream().allMatch(o -> o.getAge() > 17);
//判断所有员工的年龄是不是都大于17岁,如果有一个返回false,总体返回false
System.out.println(allMatch);
//false
boolean anyMatch = list.stream().anyMatch(o -> o.getSalary() >= 7000);
//判断是否有一个员工的工资大于7000
System.out.println(anyMatch);
//true
boolean noneMatch = list.stream().noneMatch(o -> o.getSalary() > 10000);
//判断是不是没有员工的工资大于1w
System.out.println(noneMatch);
//true
}
}
package org.westos.demo3;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author lwj
* @date 2020/6/20 16:38
*/
public class MyTest2 {
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//获取最高工资的员工
Optional<Employee> first = list.stream().sorted((o1, o2) -> Double.compare(o2.getSalary(), o1.getSalary())).findFirst();
//Optional<Employee> first = list.stream().min((o1, o2) -> Double.compare(o2.getSalary(), o1.getSalary()));
//min(Comparator c)
//Optional 容器 调用get()
Employee employee = first.get();
System.out.println(employee);
//Employee [id=101, name=张三, age=18, salary=9999.99, status=null]
//获取最高工资
Double maxSalary = list.stream().map(Employee::getSalary).sorted((o1, o2) -> Double.compare(o2, o1)).findFirst().get();
//Double maxSalary = list.stream().map(Employee::getSalary).min((o1, o2) -> Double.compare(o2, o1)).get();
System.out.println(maxSalary);
//9999.99
//Employee employee1 = list.stream().findAny();
//随机获取一个员工,串行流,每次随机都是获取第一个员工
//System.out.println(employee1);
Optional<Employee> employee1 = list.parallelStream().findAny();
//并行流
System.out.println(employee1.get());
//去重后统计流中元素个数
long count = list.stream().distinct().count();
System.out.println(count);
//5
}
}
归约
package org.westos.demo3;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
/**
* @author lwj
* @date 2020/6/20 16:58
*/
public class MyTest3 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(10, 20, 30, 40);
/*Optional<Integer> reduce = list.stream().reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
});*/
Integer sum = list.stream().reduce(Integer::sum).get();
/*
public static int sum(int a, int b) {
return a + b;
}
*/
System.out.println(sum);
//100
Integer reduce = list.stream().reduce(10, Integer::sum);
System.out.println(reduce);
//参数一:起始值
//110
//求员工总工资
List<Employee> list2 = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
Double aDouble = list2.stream().map(Employee::getSalary).reduce(Double::sum).get();
System.out.println(aDouble);
//48888.84000000001
}
}
收集
package org.westos.demo3;
import org.westos.demo.Employee;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author lwj
* @date 2020/6/20 17:06
*/
public class MyTest4 {
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
Stream<String> nameStream = list.stream().map(Employee::getName).distinct();
Set<String> collect = nameStream.collect(Collectors.toSet());
//把流中的数据元素放到Set集合
System.out.println(collect);
//[李四, 张三, 王五, 赵六, 田七]
Stream<Integer> integerStream = list.stream().map(Employee::getAge);
List<Integer> collect1 = integerStream.collect(Collectors.toList());
//把流中的数据元素收集到List集合
System.out.println(collect1);
//[59, 18, 28, 8, 8, 8, 38]
Stream<Integer> integerStream1 = list.stream().map(Employee::getId);
ArrayList<Integer> collect2 = integerStream1.collect(Collectors.toCollection(ArrayList::new));
//把流中的数据元素收集到指定集合中
System.out.println(collect2);
//[102, 101, 103, 104, 104, 104, 105]
String collect3 = list.stream().map(Employee::getName).distinct().collect(Collectors.joining("-", "[", "]"));
//拼接流中的所有元素
System.out.println(collect3);
//[李四-张三-王五-赵六-田七]
}
}
求总工资、平均工资、最大工资、最小工资
package org.westos.demo3;
import org.westos.demo.Employee;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author lwj
* @date 2020/6/20 17:25
*/
public class MyTest5 {
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
double average = collect.getAverage();
//获取平均工资
System.out.println(average);
//6984.120000000001
double sum = collect.getSum();
//获取总工资
System.out.println(sum);
//48888.840000000004
double max = collect.getMax();
//获取最大工资
System.out.println(max);
//9999.99
double min = collect.getMin();
//获取最低工资
System.out.println(min);
//3333.33
}
}
以上是关于33JDK1.8新特性(Lambda表达式Stream流)的主要内容,如果未能解决你的问题,请参考以下文章