filter就是调用test,forEach分别调用accept,collect把流生成一个list,map()返回一个Stream

函数式接口

和时间有关的API
java1.8之前:java.util.Date; 不好的设计
Date是一个可变的对象
java1.8之后推荐用LocalDate

public class App {
    public static void main(String[] args) {
        //可变的,不推荐使用
        Date date = new Date();
        System.out.println(date);
        date.setYear(date.getYear() + 1);
        System.out.println(date);

        //java1.8之后应该用LocalDate  LocalDateTime
        LocalDate day = LocalDate.now();
        System.out.println(day);
        LocalDate day2 = day.plusDays(1);
        System.out.println(day2);

        //不可变的,举例
        BigDecimal a = new BigDecimal("100");
        System.out.println(a);
        BigDecimal b = a.add(new BigDecimal("200"));
        System.out.println(b);
    }
}

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
学好Lambda
1、熟悉泛型 2、熟练Steam API

这里写图片描述
函数式接口:
只有一个抽象方法(Object类中的方法除外)的接口是函数式接口

@FunctionalInterface
public interface UserMapper {

    int delete(); //这个才是

    public int hashCode();  //这个不是

    default int insert(){  //default不算
        return 1;
    }
}

例如JDK1.8自带的:
package java.lang;
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}


package java.util.concurrent;
@FunctionalInterface
public interface Callable<V> {  //带泛型的

    V call() throws Exception;
}

这里写图片描述

Lamba表达式

这里写图片描述
这里写图片描述
左边是参数,右边是body体。body体是实现了函数式接口抽象方法的内容
例如上面的Runnable,run方法是没有参数的所以是个空括号,右边是方法的具体实现。
这里写图片描述
这里写图片描述
Lambda表达式可以自动推断参数类型
这里写图片描述

static void test() throws Exception {
        Runnable r1 = new Runnable()  {   //不使用
            public void run() {
                System.out.println("run");
            }
        };
        r1.run();

        //无参无返回值
        Runnable r2 = () -> {System.out.println("run");};
        r2.run();

        Runnable r3 = () -> System.out.println("run");
        r3.run();

        //无参有返回值
        Callable<String> c1 = new Callable<String>() {
            public String call() throws Exception {
                return "hello";
            }
        };

        //不需要也不允许使用throws语句来声明它可能会抛出的异常,再外面抛
        Callable<String> c2 = () -> {return "hello";};
        Callable<String> c3 = () -> "hello";

        System.out.println(c1.call());
        System.out.println(c2.call());
        System.out.println(c3.call());

        //有参无返回值
        UserMapper u1 = new UserMapper() {
            public void insert(User user) {
                System.out.println("insert user: " + user);
            }
        };

        UserMapper u2 = (user) -> {System.out.println("insert user: " + user);};  //类型可以省略
        UserMapper u3 = (User user) -> System.out.println("insert user: " + user);

        u1.insert(new User());
        u2.insert(new User());
        u3.insert(new User());

        //有参有返回值的
        OrderMapper o1 = new OrderMapper() {
            public int insert(Order order) {
                System.out.println("insert order: " + order);
                return 1;
            }
        };

        OrderMapper o2 = (order) -> {return 1;};
        OrderMapper o3 = (Order order) -> {return 1;};
        OrderMapper o4 = (order) -> 1;
        OrderMapper o5 = (Order order) -> 1;
        System.out.println(o1.insert(new Order()));
        System.out.println(o2.insert(new Order()));
        System.out.println(o3.insert(new Order()));
        System.out.println(o4.insert(new Order()));
        System.out.println(o5.insert(new Order()));

        //输入 输出都是Integer
        Function<Integer, Integer> f1 = a -> {
            int sum = 0;
            for(int i=1;i<=a;i++) {
                sum += i;
            }
            return sum;
        };

        System.out.println(f1.apply(10));
    }

写Lambda表达式:一看参数,二看返回值

public class App  {
    public static void main(String[] args) throws Exception {
        //
        Runnable r1 = () -> get(); //run方法没有返回值,get有返回值,run可以不返回
        Runnable r2 = () -> exec();

//      Runnable r3 = () -> 100;  //直接返回值是不行的,而void可以不返回
//      Runnable r4 = () -> "";

        Foo f1 = () -> get();
//      Foo f2 = () -> find();
//      Foo f3 = () -> exec();  //get有返回值,但是exec没有返回值,不行,返回值不一致也不行

        Foo f4 = () -> 100;
        Foo f5 = () -> true ? 1 : -1;

        BiFunction<String, String, Integer> bf = (a, b) -> a.length() + b.length();  //两个输入一个输出
        System.out.println(bf.apply("java", "se"));

        BiFunction<String, String, Integer> bf1 = (a, b) -> {
            //doing
            return 1;
        };

        Function<String, Integer> f6 = a -> a.length();
        System.out.println(f6.apply("javaee"));
    }
}

interface Foo {
    int get();
}
方法的引用

静态方法引用

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 静态方法引用
 * 如果函数式接口的实现恰好是通过调用一个静态方法来实现(其他什么都没干),那么就可以使用静态方法引用
 * 
 *  语法
 *  类名::staticMethod
 */
public class Example2 {

    public static String put() {
        System.out.println("put method invoke");
        return "hello";
    }

    public static void con(Integer size) {
        System.out.println("size: " + size);
    }

    public static String toUpperCase(String str) {
        return str.toUpperCase();
    }

    public static Integer len(String s1, String s2) {
        return s1.length() + s2.length();
    }

    public static void main(String[] args) {
        //只有一个输出
        Supplier<String> s = () ->d'de'de Example2.put();
        Supplier<String> s1 = () -> Fun.ret();

        Supplier<String> s2 = Example2::put;
        Supplier<String> s3 = Fun::ret;
        System.out.println(s1.get());

        //一个输入
        Consumer<Integer> c1 = (size) -> Example2.con(size);
        Consumer<Integer> c2 = Example2::con;
        c2.accept(100);


        Function<String, String> f1 = str -> str.toUpperCase();  //实例方法
        Function<String, String> f2 = str -> Example2.toUpperCase(str);
        Function<String, String> f3 = Example2::toUpperCase;
        Function<String, String> f4 = Fun::toUpperCase;
        System.out.println(f3.apply("lambda"));

        BiFunction<String, String, Integer> bf1 = (ss1, ss2) -> ss1.length() + ss2.length();
        BiFunction<String, String, Integer> bf2 = (ss1, ss2) -> Example2.len(ss1, ss2);
        BiFunction<String, String, Integer> bf3 = Example2::len;
        System.out.println(bf3.apply("java", "se"));
    }

}
class Fun {
    public static String ret() {
        System.out.println("put method invoke");
        return "hello";
    }

    public static String toUpperCase(String str) {
        return str.toUpperCase();
    }
}

静态方法的引用

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 实例方法引用
 * 如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现(其他什么都没干),那么就可以使用实例方法引用
 * 
 *  语法
 *  inst::instMethod
 */
public class Example3 extends Base {

    public String put() {
        return "hello";
    }

    public void con(Integer size) {
        System.out.println("size : " + size);
    }

    public String toUpper(String str) {
        System.out.println("current to upper");
        return str.toUpperCase();
    }

    public void test() {
        Function<String, String> f4 = this::toUpper;
        System.out.println(f4.apply("javame"));

        Function<String, String> f5 = super::toUpper;
        System.out.println(f5.apply("javame"));
    }

    public static void main(String[] args) {
        Supplier<String> s = () -> new Example3().put();
        Supplier<String> s1 = () -> {return new Example3().put();};
        Supplier<String> s2 = new Example3()::put;
        System.out.println(s2.get());

        Example3 exam = new Example3();
        exam.test();

        Consumer<Integer> c1 = (size) -> new Example3().con(size);
        Consumer<Integer> c2 = new Example3()::con;
        Consumer<Integer> c3 = exam::con;
        c2.accept(100);
        c3.accept(100);

        Function<String, String> f1 = str -> str.toUpperCase();
        Function<String, String> f2 = str -> exam.toUpper(str);
        Function<String, String> f3 = str -> new Example3().toUpper(str);
        Function<String, String> f4 = exam::toUpper;
        Function<String, String> f5 = new Example3()::toUpper;
        System.out.println(f4.apply("javase"));
        System.out.println(f5.apply("javaee"));
    }

}
/**
 * 对象方法引用
 * 抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。
 * 如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
 * 
 * 
 * 第一个参数类型 最好是自定义的类型
 * 
 *  语法
 *  类名::instMethod
 */
public class Example4 {

    /**
     * 抽象方法没有输入参数,不能使用对象方法引用
     * 比如说,如下函数式接口
     */
    public void not() {
        Runnable run = () -> {};
        Closeable c = () -> {};
        Supplier<String> s = () -> "";
    }

    public static void main(String[] args) {
        Consumer<Too> c1 = (Too too) -> new Too().foo();
        Consumer<Too> c2 = (Too too) -> new Too2().foo(); //不能使用对象方法引用
        Consumer<Too> c3 = Too::foo;

        c1.accept(new Too());
        c3.accept(new Too());

        BiConsumer<Too2, String> c5 = (too2, str) -> new Too2().fo(str);
        BiConsumer<Too2, String> c6 = Too2::fo;

        BiFunction<Prod, String, Integer> bf1 = (p, s) -> new Prod().fun(s);
        BiFunction<Prod, String, Integer> bf2 = (p, s) -> new Too().fun(s);
        BiFunction<Prod, String, Integer> bf3 = Prod::fun;

        Execute ex1 = (p,name,size) -> new Prod().run(name, size);
        Execute ex2 = Prod::run;
    }

}

interface Execute {
    public void run(Prod p, String name, String size);
}

class Prod {

    public void run(String name, String size) {

    }

    public Integer fun(String s) {
        return 1;
    }

}

class Too {
    public Integer fun(String s) {
        return 1;
    }

    public void foo() {
        System.out.println("invoke");
    }
}

class Too2 {

    public void foo() {
        System.out.println("invoke");
    }

    public void fo(String str) {

    }
}

/**
 * 构造方法引用
 * 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
 * 
 * 
 *  语法
 *  类名::new
 */
public class Example5 {

    public static void main(String[] args) {
        Supplier<Person> s1 = () -> new Person();
        Supplier<Person> s2 = Person::new;
        s1.get();
        s2.get();

        Supplier<List> s3 = ArrayList::new;
        Supplier<Thread> s4 = Thread::new;
        Supplier<Set> s5 = HashSet::new;
        Supplier<String> s6 = String::new;

        Consumer<Integer> c1 = (age) -> new Account(age); 
        Consumer<Integer> c2 = Account::new;
        c2.accept(123);

        Function<String, Integer> fu = (str) -> Integer.valueOf(str);
        Function<String, Integer> fu1 = Integer::valueOf;

        Function<String, Account> fu2 = (str) -> new Account(); 
        Function<String, Account> fu3 = Account::new;
        fu3.apply("admin");
    }

}

class Account {
    public Account() {
        System.out.println("Account");
    }
    public Account(int age) {
        System.out.println("Account(age)");
    }
    public Account(String name) {
        System.out.println("Account(name)");
    }
}

class Person {
    public Person() {
        System.out.println("new Person()");
    }
}
Stream

这里写图片描述
Stream先创建,再中间,再终止

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

代码示例

public class App  {
    //通过集合和数组的方式创建流最常见
    //1、通过数组
    static void gen1() {
        //stream调用consumer的accept方法,函数式接口只有一个抽象方法
        String[] arr = {"a", "b", "1", "2"};
        Stream<String> stream = Stream.of(arr); //先转成stream流
        stream.forEach(System.out::println);  //简写
        //等价于如下写法:
        stream.forEach((input) -> System.out.println(input));  //Lambda表达式可以自动推断参数类型 
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
    }
    //2、通过集合
    static void gen2() {
        List<String> list = Arrays.asList("a", "b", "1", "2");
        Stream<String> stream = list.stream();  //集合里面什么类型流里面就是什么类型
        stream.forEach(System.out::println);
    }

    //gen3gen4生成的是一个无止境的流,会一直在foreach循环
    static void gen3() {
        //generate 一直调用Supplierget方法,这时候用limit只截取前面10个     
        Stream<Integer> stream = Stream.generate( () -> 1);  //里面传一个输出Supplier,返回的就是输出的类型
        stream.limit(10).forEach(System.out::println);
    }

    static void gen4() {
        //iterate(final T seed, final UnaryOperator<T> f)  //相同类型的输入输出
        Stream<Integer> stream = Stream.iterate(1, x -> x + 1); 
        stream.limit(10).forEach(System.out::println);
    }

    //通过其他的API创建stream
    static void gen5() throws Exception {
        String str = "abcd";
        IntStream stream = str.chars();

//      stream.forEach(x -> System.out.println(x));
        stream.forEach(System.out::println);

        Files.lines(Paths.get("d:/Person.java")).forEach(System.out::println);
    }

    public static void main(String[] args) throws Exception {
//      App.gen1();
//      App.gen2();
//      App.gen3();
//      App.gen4();
//      App.gen5();

        //没有终止操作是不会filter
        //filter(Predicate<? super T> predicate) predicate中的方法:boolean test(T t);  filter就是调用test
        //过滤test返回为true的元素,得到一个新的streammapToInt转成一个IntStream
        Arrays.asList(1,2,3,4,5).stream().filter(x -> x%2 == 0).forEach(System.out::println);
        int sum = Arrays.asList(1,2,3,4,5,6).stream().filter(x -> x%2 == 0).mapToInt(x -> x).sum();
        System.out.println(sum);

        //max(Comparator<? super T> comparator);  comparator中的方法:int compare(T o1, T o2);
        //max() 返回的也是Optional
        int max = Arrays.asList(1,2,3,4,5,6).stream().max((a,b) -> a-b).get();
        System.out.println(max);

        int min = Arrays.asList(1,2,3,4,5,6).stream().min((a,b) -> a-b).get();
        System.out.println(min);

        Optional<Integer> op = Arrays.asList(1,2,3,4,5,6).stream().filter(x -> x%2 == 0).findAny();  //findAny有可能找不到,返回有可能是空,所以返回的是一个Optional
        System.out.println(op.get());

        op = Arrays.asList(1,2,3,4,5,6).stream().filter(x -> x%2 == 0).findFirst();
        System.out.println(op.get());

        //排序sorted()  默认是从小到大,逆序就是b-a sorted()里面也是Comparator
        op = Arrays.asList(1,2,3,4,5,6).stream().filter(x -> x%2 == 0).sorted((a,b) -> b-a).findFirst();
        System.out.println(op.get());


        Arrays.asList(11,3,8,5,10).stream().sorted().forEach(System.out::println); //正序
        Arrays.asList(11,3,8,5,10).stream().sorted((a,b) -> b-a).forEach(System.out::println);//倒序
        Arrays.asList("cn", "admin", "net", "io").stream().sorted((a,b) -> a.length()-b.length()).forEach(System.out::println); //字符串可以根据长度排序

//        终止方法:收集collect,参数是一个普通的接口Collector。自己去实现Collector比较麻烦,可以用Collectors里面的静态方法来生成Collector
//        从1-50里面的所有偶数找出来,放到一个list里面。toList可以生成一个Collector
        List<Integer> list = Stream.iterate(1, x -> x + 1).limit(50).filter(x -> x%2 == 0).collect(Collectors.toList());
        System.out.println(list);

        //distinct去重
        Arrays.asList(1, 3, 4, 2, 2, 5, 1).stream().distinct().forEach(System.out::println);

        Set<Integer> set = Arrays.asList(1, 3, 4, 2, 2, 5, 1).stream().collect(Collectors.toSet());
        System.out.println(set);

        //下面讲转换mapmap()转换就是把stream流里面的每个元素变成别的类型,所以传入的是一个输入,一个输出,map自己会循环
        //把下列字符串分割,依次转换成int,然后求和
//      String str = "11,22,33,44,55";
//      int sum  = Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum();
//      System.out.println(sum);
//
//      sum  = Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum();
//      System.out.println(sum);
//
//      sum  = Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum();
//      System.out.println(sum);

        //把字符串转换成一个个的User对象
//      String str = "tomcat,nginx,apahce,jetty";
//      Stream.of(str.split(",")).map(x -> new User(x)).forEach(System.out::println);
//      Stream.of(str.split(",")).map(User::new).forEach(System.out::println);
//      Stream.of(str.split(",")).map(x -> Person.build(x)).forEach(System.out::println);
//      Stream.of(str.split(",")).map(Person::build).forEach(System.out::println);

        String str = "11,22,33,44,55";
        //peek遍历的时候调用每个元素去消费。例如:求和之前打印出每个元素,类似于日志
        int sum  = Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum();
        System.out.println(sum);
    }

}

class User {
    private String name;
    public User(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User [name=" + name + "]";
    }
}

class Person {
    private String name;

    public static Person build(String name) {
        Person p = new Person();
        p.setName(name);
        return p;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
}
并行流
import java.util.Optional;
import java.util.stream.Stream;

public class App  {
    public static void main(String[] args) throws Exception {
        //-Djava.util.concurrent.ForkJoinPool.common.parallelism=5

        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "5");

        //使用并行流,也就是多个线程并行的去执行任何。自己要实现这个,用三行代码肯定搞不定,而用parallel就很容易实现
        //而sequential()可以把一个并行流又变成一个顺序流。。谁在最后就是什么流
        Optional<Integer> max = Stream.iterate(1, x -> x+1).limit(200).peek(x -> {
            //内部迭代的时候就输出它的线程
            System.out.println(Thread.currentThread().getName());
        }).parallel().max(Integer::compare);

        System.out.println(max);
    }
}

例子:test1 、2 、5、8 重点掌握。(list转string,map)
map()还是返回一个stream,但是collect(Collectors.toMap()) 可以转成map

package com.edu.java8.lambda;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Test;

public class LambdaTest {

    /**
     * index.do?itemId=1&userId=10000&type=20&token=111111111111&key=index
     */
    @Test
    public void test1() {
        //map转换-->中间操作
        //queryString.split("&") 1、第一步分割后得到一个数组 [itemId=1,userId=10000]
        //第二步map转换:输入的是字符串,输出的是字符串数组  [[itemId,1] ,[userId,1000] ]
        //Collectors.toMap转成map。    
        //toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper)
        String queryString = "itemId=1&userId=10000&type=20&token=111111111111&key=index";
        Map<String, String> params = Stream.of(queryString.split("&")).map(str -> str.split("=")).collect(Collectors.toMap(s -> s[0], s -> s[1]));
        System.out.println(params);
    }

    @Test
    public void test2 () {
        List<Integer> ids = books().stream().map( book -> book.getId()).collect(Collectors.toList());
        System.out.println(ids);

        ids = books().stream().map(Book::getId).collect(Collectors.toList());
        System.out.println(ids);

        list转成string,list先变成stream,stream再通过collect变成string即可
        //book.getId()+""把id转成字符串,然后把前面的值都join起来
        //joining() 返回一个字符串
        //1,2,3
        String str = books().stream().map(book -> book.getId()+"").collect(Collectors.joining(","));
        System.out.println(str);

        //(1,2,3)  在字符串前后各加一个括号
        str = books().stream().map(book -> book.getId()+"").collect(Collectors.joining(",", "(", ")"));
        System.out.println(str);

        //('1','2','3')
        str = books().stream().map(book -> "'"+book.getId()+"'").collect(Collectors.joining(",", "(", ")"));
        System.out.println(str);
    }

    //list转list
    @Test
    public void test3 () {
        List<String> list = books().stream().map(Book::getType).collect(Collectors.toList());
        System.out.println(list);

        list = books().stream().map(Book::getType).distinct().collect(Collectors.toList());
        System.out.println(list);

        //转成set也可以去重
        Set<String> set = books().stream().map(Book::getType).collect(Collectors.toSet());
        System.out.println(set);
    } 


    @Test
    public void test4 () {
//      books().stream().sorted((book1, book2) -> Double.compare(book1.getPrice(), book2.getPrice())).forEach(System.out::println);;

        //价格从高到低排序
//      Comparator<Book> compa = (book1, book2) -> Double.compare(book1.getPrice(), book2.getPrice());
//      books().stream().sorted(compa.reversed()).forEach(System.out::println);


//      Comparator<Book> compa = (book1, book2) -> Double.compare(book1.getPrice(), book2.getPrice());
//      books().stream().sorted(compa.thenComparing((book1,book2) -> book1.getPublishDate().isAfter(book2.getPublishDate()) ? -1 : 1)).forEach(System.out::println);

//      books().stream().sorted(Comparator.comparing(Book::getPrice)).forEach(System.out::println);
//      books().stream().sorted(Comparator.comparing(Book::getPrice).reversed()).forEach(System.out::println);
        books().stream().sorted(Comparator.comparing(Book::getPrice).reversed().thenComparing(Comparator.comparing(Book::getPublishDate).reversed())).forEach(System.out::println);
    }

    @Test
    public void test5 () {
        //直接收集,不用map转换
//      Map<Integer, Book> booksMap = books().stream().collect(Collectors.toMap(book -> book.getId(), book -> book));
//      System.out.println(booksMap);

        Map<Integer, Book> booksMap = books().stream().collect(Collectors.toMap(Book::getId, book -> book));
        System.out.println(booksMap);
    }


    @Test
    public void test6 () {
        //计算书的平均价格
        Double avg = books().stream().collect(Collectors.averagingDouble(Book::getPrice));
        System.out.println(avg);
    }

    @Test
    public void test7 () {
        //找最贵的书
        //返回的是一个Optional,有可能没找到
        Optional<Book> book = books().stream().collect(Collectors.maxBy(Comparator.comparing(Book::getPrice)));
        System.out.println(book);

        //找最便宜的书
        book = books().stream().collect(Collectors.minBy(Comparator.comparing(Book::getPrice)));
        System.out.println(book);

        //找时间最早的书
        book = books().stream().collect(Collectors.minBy(Comparator.comparing(Book::getPublishDate)));
        System.out.println(book);

        //找发布时间最晚的书
        book = books().stream().collect(Collectors.maxBy(Comparator.comparing(Book::getPublishDate)));
        System.out.println(book);

        //找最贵的,但是最晚出来的书
        Comparator<Book> comp = Comparator.comparing(Book::getPrice);
        book = books().stream().collect(Collectors.maxBy(comp.thenComparing(Comparator.comparing(Book::getPublishDate))));
        System.out.println(book);
    }

    @Test
    public void test8 () {
        //List转成Map
        //分组:找相同类型的书。。 先转成map,再遍历map
        //Collectors.groupingBy 返回的是一个map
//      Map<String, List<Book>> booksMap = books().stream().collect(Collectors.groupingBy(Book::getType));
//      booksMap.keySet().forEach(key -> {
//          System.out.println(key);
//          System.out.println(booksMap.get(key));
//          System.out.println("---------------------");
//      });
//      
        //每种类型的个数
//      Map<String, Long> booksCount = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.counting()));
//      System.out.println(booksCount);

//      Map<String, Double> booksSum = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.summingDouble(Book::getPrice)));
//      System.out.println(booksSum);

//      Map<String, Double> booksSum = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.averagingDouble(Book::getPrice)));
//      System.out.println(booksSum);

//      Map<String, Optional<Book>> booksMaxPrice = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.maxBy(Comparator.comparing(Book::getPrice))));
//      System.out.println(booksMaxPrice);
//      
//      Map<String, Optional<Book>> booksMinPrice = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.minBy(Comparator.comparing(Book::getPrice))));
//      System.out.println(booksMinPrice);

        Map<String, Optional<Book>> booksMaxPubDate = books().stream().collect(Collectors.groupingBy(Book::getType, Collectors.maxBy(Comparator.comparing(Book::getPublishDate))));
        System.out.println(booksMaxPubDate);
    }

    //过滤
    //80块钱以上的书,按照时间从小到大排序
    @Test
    public void test9 () {
        books().stream().filter(book -> book.getPrice() >= 80).sorted(Comparator.comparing(Book::getPublishDate).reversed()).forEach(System.out::println);;
    }

    private List<Book> books(){
        List<Book> books = new ArrayList<>();
        books.add(new Book(1, "tomcat", 70d, "服务器", LocalDate.parse("2014-05-17")));
        books.add(new Book(2, "jetty", 60d, "服务器", LocalDate.parse("2015-12-01")));
        books.add(new Book(3, "nginx", 65d, "服务器", LocalDate.parse("2016-10-17")));
        books.add(new Book(4, "java", 66d, "编程语言", LocalDate.parse("2011-04-09")));
        books.add(new Book(5, "ruby", 80d, "编程语言", LocalDate.parse("2013-05-09")));
        books.add(new Book(6, "php", 40d, "编程语言", LocalDate.parse("2014-08-06")));
        books.add(new Book(7, "html", 44d, "编程语言", LocalDate.parse("2011-01-06")));
        books.add(new Book(8, "oracle", 150d, "数据库", LocalDate.parse("2013-08-09")));
        books.add(new Book(9, "mysql", 66d, "数据库", LocalDate.parse("2015-04-06")));
        books.add(new Book(10, "ssh", 70d, "编程语言", LocalDate.parse("2016-12-04")));
        books.add(new Book(11, "设计模式", 81d, "其他", LocalDate.parse("2017-04-06")));
        books.add(new Book(12, "重构", 62d, "其他", LocalDate.parse("2012-04-09")));
        books.add(new Book(13, "敏捷开发", 72d, "其他", LocalDate.parse("2016-09-07")));
        books.add(new Book(14, "从技术到管理", 42d, "其他", LocalDate.parse("2016-02-19")));
        books.add(new Book(15, "算法导论", 66d, "其他", LocalDate.parse("2010-05-08")));
        books.add(new Book(16, "oracle 12c", 150d, "数据库", LocalDate.parse("2017-05-08")));
        return books;
    }
}
package com.edu.java8.lambda;

import java.time.LocalDate;

public class Book {
    private int id;
    private String name;
    private double price;
    private String type;
    private LocalDate publishDate;

    public Book(int id, String name, double price, String type, LocalDate publishDate) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.type = type;
        this.publishDate = publishDate;
    }
    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 double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public LocalDate getPublishDate() {
        return publishDate;
    }
    public void setPublishDate(LocalDate publishDate) {
        this.publishDate = publishDate;
    }
    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", price=" + price + ", type=" + type + ", publishDate="
                + publishDate + "]";
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值