java lambda & stream api
阿新 • • 發佈:2020-07-20
Lambda
Scenario 1
@Test
public void testLambda1(){
new Thread(()->{
System.out.println("Hello? Is Frank in?");
}).start();
new Thread(()->{
System.out.println("Yeah?");
}).start();
}
Scenario 2
@Test
public void testConsumer(){
// Before Use Lambda
Consumer
@Override
public void accept(String s) {
System.out.println(s);
}
};
con1.accept("Love");
// After Use Lambda
Consumer<String> con2 = (s) ->{
System.out.println(s);
};
con2.accept("Family");
}
Scenario 3
Actually I used in scenario 2
Scenario 4
Consumer<String> con3 = s -> System.out.println(s); con3.accept("Phoenix");
Scenario 5
@Test
public void testComparator(){
// Before Lambda Expression
Comparator
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
// After Use Lambda Expression Comparator<Integer> com2 = (o1, o2) ->{ return o1.compareTo(o2); }; }
Scenario 6
I used it in Scenario 4
The Big Four Functional Interfaces
Consumer
@Test
public void testFunctional1(){
// Before Lambda
happyTime(500, new Consumer<Double>() {
@Override
public void accept(Double aDouble) {
System.out.println("I have " + aDouble + " dollars.");
}
});
// After Lambda
happyTime(600, money-> System.out.println("I have " + money + " dollars."));
}
public void happyTime(double money, Consumer<Double> con){
con.accept(money);
}
Predicate
@Test
public void testPredicate(){
List<String> listOld = new ArrayList<>();
List<String> listNew = new ArrayList<>();
listOld.add("Love");
listOld.add("Tom");
listOld.add("Truman");
listOld.add("Villanelle");
listOld.add("JackUltraman");
// Before Lambda
listNew = filterString(listOld, new Predicate<String>() {
@Override
public boolean test(String s) {
if(s.length() > 5){
return true;
}else{
return false;
}
}
});
// Iterator<String> iterator = listNew.iterator();
// if(iterator.hasNext()){
// System.out.println(iterator.next());
// }
for(String s : listNew){
System.out.println(s);
}
// After Lambda
List<String> listNew2 = new ArrayList<>();
listNew2 = filterString(listOld, s -> {
if(s.length() > 5) return true;
else return false;
});
for(String s : listNew2){
System.out.println(s);
}
}
public List<String> filterString(List<String> list, Predicate<String> pre){
List<String> filterList = new ArrayList<>();
for(String s : list){
if(pre.test(s)){
filterList.add(s);
}
}
return filterList;
}
Method References
@Test
public void testMethodReference(){
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("Phoenix City");
System.out.println("*****************************************");
Consumer<String> con2 = System.out::println;
con2.accept("Chicago");
}
Stream
get a stream
public class StreamTest {
List<Employee> employees = new ArrayList<>();
@Test
public void test1(){
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1002, "Jerry", 24, 189.80));
employees.add(new Employee(1003, "Kate", 22, 289.80));
employees.add(new Employee(1004, "Lucy", 25, 389.80));
employees.add(new Employee(1005, "McEncy", 27, 489.80));
employees.add(new Employee(1006, "Red", 28, 589.80));
employees.add(new Employee(1007, "Jack", 29, 689.80));
employees.add(new Employee(1008, "Robert", 33, 989.80));
Stream<Employee> stream = employees.stream();
}
int[] arr = {1, 2, 3, 4};
IntStream stream1 = Arrays.stream(arr);
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
The Operation of Stream API
@Test
public void testStream1(){
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1002, "Jerry", 24, 189.80));
employees.add(new Employee(1003, "Kate", 22, 289.80));
employees.add(new Employee(1004, "Lucy", 25, 389.80));
employees.add(new Employee(1005, "McEncy", 27, 489.80));
employees.add(new Employee(1006, "Red", 28, 589.80));
employees.add(new Employee(1007, "Jack", 29, 689.80));
employees.add(new Employee(1008, "Robert", 33, 989.80));
employees.stream().filter(e->e.getSalary() > 600).forEach(System.out::println); // here, foreach() is important, otherwise the filter() won't work
// the output is :
// Employee{id=1001, name='Tom', age=23, salary=789.8}
// Employee{id=1007, name='Jack', age=29, salary=689.8}
// Employee{id=1008, name='Robert', age=33, salary=989.8}
// limit()
employees.stream().limit(3).forEach(System.out::println);
// the output is the first 3 line of the list
}
@Test
public void testStream2(){
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.stream()
.distinct()
.forEach(System.out::println);
// the output is only one line:
// Employee{id=1001, name='Tom', age=23, salary=789.8}
}
@Test
public void testStreamMap(){
List<String> list = new ArrayList<>();
list.add("make");
list.add("friends");
list.add("with");
list.add("you");
list.stream()
.map(str -> str.toUpperCase())
.forEach(System.out::println); // MAKE FRIENDS WITH YOU
}
if there is an object, then first map(), then filter()
flatmap() to map() is just like addAll() to add()
that means map() can return a stream which has many steams in it, while flatmap() will only return you a stream
sorted
@Test
public void testSort1(){
// 自然排序
List<Integer> list = Arrays.asList(45, 32, 78, 9, 23, 88);
list.stream()
.sorted()
.forEach(System.out::println);
// 定製排序
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1002, "Jerry", 24, 189.80));
employees.add(new Employee(1003, "Kate", 22, 289.80));
employees.add(new Employee(1004, "Lucy", 25, 389.80));
employees.add(new Employee(1005, "McEncy", 27, 489.80));
employees.add(new Employee(1006, "Red", 28, 589.80));
employees.add(new Employee(1007, "Jack", 29, 689.80));
employees.add(new Employee(1008, "Robert", 33, 989.80));
employees.stream()
.sorted((e1, e2)->{ // here you use Comparator interface
return Integer.compare(e1.getAge(), e2.getAge());
})
.forEach(System.out::println);
}
終止操作
@Test
public void testTerminate(){
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1002, "Jerry", 24, 189.80));
employees.add(new Employee(1003, "Kate", 22, 289.80));
employees.add(new Employee(1004, "Lucy", 25, 389.80));
employees.add(new Employee(1005, "McEncy", 27, 489.80));
employees.add(new Employee(1006, "Red", 28, 589.80));
employees.add(new Employee(1007, "Jack", 29, 689.80));
employees.add(new Employee(1008, "Robert", 33, 989.80));
// allMatch(Predicate pre)
boolean b = employees.stream()
.allMatch(e -> e.getAge() > 18);
System.out.println(b); // true
// anyMatch(Predicate pre)
boolean b1 = employees.stream()
.anyMatch(e -> e.getSalary() > 700);
System.out.println(b1); // true
// noneMatch(Predicate pre)
// 是否沒有員工超過60歲
boolean b2 = employees.stream()
.noneMatch(e1 -> e1.getAge() > 60);
System.out.println(b2); // true :
// findFirst() : 返回第一個元素
Optional<Employee> employee = employees.stream()
.findFirst();
System.out.println(employee); // Optional[Employee{id=1001, name='Tom', age=23, salary=789.8}]
// findAny()
Optional<Employee> employee1 = employees.parallelStream() // findAny() in stream always find the first one
.findAny(); // but when you use parallel stream, things gonna be different
System.out.println(employee1);
// count()
long count = employees.stream()
.filter(e1 -> e1.getSalary() > 600)
.count();
System.out.println(count); // 3
// max(Comparator c)
Optional<Double> max = employees.stream()
.map(Employee::getSalary)
.max((x, y) -> Double.compare(x, y));
System.out.println(max); // Optional[989.8]
}
Reduce
@Test
public void testReduce(){
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer reduce = list.stream()
.reduce(0, Integer::sum);
System.out.println(reduce); // 55
}
// the sum of all salary
Double reduce = employees.stream()
.map(Employee::getSalary)
.reduce(0.0, Double::sum);
System.out.println(reduce); // 4418.400000000001
Collect
@Test
public void testCollect(){
employees.add(new Employee(1001, "Tom", 23, 789.80));
employees.add(new Employee(1002, "Jerry", 24, 189.80));
employees.add(new Employee(1003, "Kate", 22, 289.80));
employees.add(new Employee(1004, "Lucy", 25, 389.80));
employees.add(new Employee(1005, "McEncy", 27, 489.80));
employees.add(new Employee(1006, "Red", 28, 589.80));
employees.add(new Employee(1007, "Jack", 29, 689.80));
employees.add(new Employee(1008, "Robert", 33, 989.80));
List<Employee> list = employees.stream()
.filter(e -> e.getSalary() > 600)
.collect(Collectors.toList());
for(Employee e1 : list){
System.out.println(e1.getName()); // Tom Jack Robert
}
}