– java 8 中引入了一个很重要的特性就是 lambda 表达式,而同时在此基础上引入的 Stream API 更是如虎添翼,让我们在处理一些匿名类和内部类的时候更加的优雅了。
– 使用 lambda 可以极大的减少代码冗余,同时让我在处理一些实现了 Stream 接口的类的时候,更加的多样性和灵活。
– 当然这里面也有很多坑,下面为平时总结的一些demo,记录下来。

/**
 * // 1. 不需要参数,返回值为 5
 * int get(){
 * return 5;
 * }
 *
 * () -> 5
 *
 * // 2. 接收一个参数(数字类型),返回其2倍的值
 * int multiple(int x){
 * return x*2;
 * }
 *
 * x -> 2 * x
 *
 * // 3. 接受2个参数(数字),并返回他们的差值
 * int subtraction(int x,int y){
 * return x-y;
 * }
 *
 * (x, y) -> x – y
 *
 * // 4. 接收2个int型整数,返回他们的和
 * int sum(int x,int y){
 * return x+y;
 * }
 *
 * (int x, int y) -> x + y
 *
 * // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
 * void print(String s){
 * System.out.print(s)
 * }
 *
 * (String s) -> System.out.print(s)
 */
public class ShareTest extends AbstractTest {

  @Test
  public void lambdaTest() {
    new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("hello world!");
      }
    }).start();

    new Thread(() -> System.out.println("hello world1!")).start();

    /**
     * 有入参和返回值的lambda的内置函数,入参可以通过泛型确定类型
     */
    Function<String, String> f = v -> v + " in java";
    System.out.println(f.apply("Function test: think"));

    /**
     * 有入参和boolean类型返回值得lambda的内置函数
     */
    Predicate<String> p = p1 -> p1.startsWith("a");
    System.out.println("Predicate test:" + p.test("abcd"));

    /**
     * 有入参和无返回值得lambda的内置函数
     */
    Consumer<String> c = c1 -> System.out.println("Consumer test:" + c1);
    c.accept("how are you!");

    /**
     * 没有入参和返回值得lambda的内置函数,主要是工厂模式的一种实现
     */
    Supplier<String> s = () -> Objects.toString(DateTime.now().getMillis());
    System.out.println("supplier now:" + s.get());

    MyInterface<String> myFunc = val -> System.out.println(val);
    myInterfaceTest(val -> val.startsWith("h"), myFunc, "hello");

  }

  public void myInterfaceTest(Predicate<String> predicate, MyInterface<String> myInterface, String a) {
    System.out.println("method processing start");
    if (predicate.test(a)) {
      myInterface.apply(a);
    }
    System.out.println("method processing start");
  }

  @FunctionalInterface
  private interface MyInterface<T> {
    void apply(T a);

    default void test() {
      System.out.println("MyInterface test");
    }

    static void test1() {
      System.out.println("MyInterface test1");
    }
  }

  /**
   * 静态方法引用:ClassName::methodName
   * 实例上的实例方法引用:instanceReference::methodName
   * 超类上的实例方法引用:super::methodName
   * 类型上的实例方法引用:ClassName::methodName
   * 构造方法引用:Class::new
   * 数组构造方法引用:TypeName[]::new
   */
  @Test
  public void funcTest() {

    /**
     * 使用已经存在的方法构造lambda函数,把过去写的东西轻松转换
     * 类型上的实例方法引用:ClassName::methodName
     */
    Consumer printlnConsumer = System.out::println;

    /**
     * 转换大写函数
     */
    Function<String, String> toUpperCaseFunc = String::toUpperCase;

    /**
     * 静态方法引用:ClassName::methodName
     */
    Consumer<String> consumer1 = ShareTest::printTest;
    consumer1.accept("Consumer test");

    /**
     * 实例上的实例方法引用:instanceReference::methodName
     */
    Student student1 = new Student();
    Function<Student, String> name1 = Student::getName;
    String tempName = name1.apply(student1);

    /**
     * 题外话,剖析Comparator.comparing(Student::getName)玩法
     */
    Stream.of(
        Student.builder().name("yubin").age("33").build(),
        Student.builder().name("houyi").age("34").build())
        .sorted(Comparator.comparing(Student::getName).thenComparing(Student::getAge))
        .forEach(printlnConsumer);

    /**
     * 实例上的实例方法引用:instanceReference::methodName
     */
    Student student2 = new Student();
    Supplier<String> getNameSupplier = student2::getName;
    String name = getNameSupplier.get();
    System.out.println("supplierName:" + name);

    /**
     * 构造方法引用:Class::new
     */
    Supplier<Student> s1 = Student::new;
    Student student3 = s1.get();
    Student student4 = s1.get();
    System.out.println("supplier student:" + student3);
    System.out.println(student3 == student4);

    /**
     * 数组构造方法引用:TypeName[]::new
     */
    IntFunction<int[]> arrayMaker = int[]::new;
    int[] array = arrayMaker.apply(10); // 创建数组 int[10]

    /**
     * 数组构造方法引用:TypeName[]::new,构建对象
     */
    Function<Integer, Student[]> studentFunc = Student[]::new;
    Student[] apply = studentFunc.apply(10);

    /**
     * 超类上的实例方法引用:super::methodName
     */
    Consumer<String> superConsumer = super::test;
    superConsumer.accept("I am super method.");

    Comparator<String> mySort = Comparator.naturalOrder();
    Stream.of("b", "a", "c").map(toUpperCaseFunc).sorted(mySort).forEach(printlnConsumer);
  }

  public static void printTest(String str) {
    System.out.println(str);
  }

  @Test
  public void streamTest() {
    System.out.println("stream start");

    for (int i = 0; i < 5; i++) {
      System.out.println(i);
    }

    Stream
        .iterate(0, item -> item + 1)
        .limit(5).forEach(System.out::println);

    System.out.println("stream -----------");

    Stream.of(1,2,3,4);

    /**
     *合并stream操作
     */
    Stream<Integer> concatStream = Stream.concat(Stream.of(1), Stream.of(2));
    concatStream.forEach(System.out::println);
    System.out.println("concat stream -----------");

    /**
     * filter过滤函数,会影响到记录的数量
     */
    Stream.of(1, 2, 3, 4, 5, 6).filter(n -> n > 3).forEach(System.out::println);
    System.out.println("stream filter -----------");

    /**
     * map转换函数,会影响到记录类型,相当于一个转换器
     */
    Stream.of(1, 2, 3, 4, 5, 6).map(n -> "A" + n).forEach(System.out::println);
    System.out.println("stream map -----------");

    /**
     * sorted排序函数,会影响到记录在容器中的顺序,基础数据类型按照自然排序,
     * 对象类型会根据排序器指定的方式进行排序,排序器需要自己提供
     */
    Stream.of(5, 2, 1, 6, 3, 4).sorted().forEach(System.out::println);
    System.out.println("stream sorted -----------");

    /**
     * 逆序的实现,Comparator提供了大量的方法帮助我们制定排序规则
     */
    Stream.of(5, 2, 1, 6, 3, 4).sorted(Comparator.reverseOrder()).forEach(System.out::println);

    /**
     * 指定排序器的方式
     */
    Stream.of(5, 2, 1, 6, 3, 4).sorted((o1, o2) -> o1.compareTo(o2)).forEach(System.out::println);

    System.out.println("stream reverseOrdered -----------");

    System.out.println("stream end");
  }

  @Test
  public void listTest() {
    System.out.println("list start");

    List<Integer> list = Lists.newArrayList(5, 2, 1, 6, 3, 4, 4);

    list.stream().filter(n -> n > 5).forEach(System.out::println);
    System.out.println("list -----------");

    /**
     * distinct依赖元素的equals方法,如果是对象类型,必须重写equals和hashcode
     */
    list.stream().distinct().forEach(System.out::println);
    System.out.println("list distinct -----------");

    /**
     * limit取N之前的数据
     */
    list.stream().limit(2).forEach(System.out::println);
    System.out.println("list limit -----------");

    /**
     * skip取跳过N之后的数据
     */
    list.stream().skip(2).forEach(System.out::println);
    System.out.println("list skip -----------");

    /**
     * collect(Collectors.toList())后每次产生的集合都是新的,不会影响原来的数据
     */
    List<Integer> newList = list.stream().filter(n -> n > 1).distinct().sorted().map(n -> n + 1).collect(Collectors.toList());
    System.out.println(list == newList);

    /**
     * 求最大值,会根据排序器排序后取最后一条
     */
    Integer maxNum = list.stream().max(Comparator.naturalOrder()).get();
    System.out.println("list max ----------- " + maxNum);

    /**
     * 求最小值,会根据排序器排序后取第一条
     */
    Integer minNum = list.stream().min(Comparator.naturalOrder()).get();
    System.out.println("list min ----------- " + minNum);

    /**
     *     int sum = 0;
     *     for(int i=0;i<10;i++){
     *       sum+=i;
     *     }
     *     return sum;
     */
    Integer total = list.stream().reduce((sum, item) -> sum + item).get();
    System.out.println("list reduce sum ----------- " + total);

    /**
     *     int sum = 1;
     *     for(int i=0;i<10;i++){
     *       sum+=i;
     *     }
     *     return sum;
     */
    int i = list.stream().reduce(1, (sum, item) -> sum + item).intValue();

    System.out.println("list reduce sum default 1 ----------- " + i);

    /**
     * 类型转换,转换成另外一个类型的流,包含不同的方法,有点类似于IO的包装类形式
     * summaryStatistics包含很多类似于统计的方法
     */
    System.out.println(list.stream().flatMapToInt(n -> IntStream.of(n)).summaryStatistics().getMax());
    System.out.println("list max -----------");

    System.out.println("list end");
  }

  @Test
  public void optionalTest() {
    /**
     * 用of构造一个Optional,当值为null会抛出异常
     */
    //    Optional<String> s1 = Optional.of(null);
    /**
     * 用ofNullable构造一个Optional,当值为null会构造一个空的Optional
     */
    Optional<String> s2 = Optional.ofNullable(null);
    /**
     * 用empty构造一个空的Optional,一般就是占位,统一返回Optional类型的参数
     */
    Optional<Object> empty = Optional.empty();
    /**
     * ifPresent 判断不为空的情况执行lamabda表达式内容
     */
    Optional<String> s3 = Optional.ofNullable("hello world!");
    s3.ifPresent(v -> System.out.println(v));

    /**
     * isPresent 返回布尔值来确定值是否为空,空的判断方法
     */
    System.out.println(s3.isPresent());

    /**
     * orElse 如果值为空,返回orElse括号中的内容
     */
    System.out.println(s2.orElse("default value"));

    /**
     * orElseGet 如果值为空,lamabda表达式中构造出的内容
     */
    System.out.println(s2.orElseGet(() -> "default value from supplier"));

    /**
     * orElseThrow 如果为空会抛出一个自己定义的异常,这里可以使用自定义异常
     * 两种形式,第一种是空构造,第二种需要用到构造函数的抛出方式
     */
    s2.orElseThrow(NullPointerException::new);
    s2.orElseThrow(() -> new NullPointerException("111"));
  }

  @Builder(toBuilder = true)
  @Getter
  @NoArgsConstructor
  @AllArgsConstructor
  @ToString
  private static class Student {
    private String name = "111";
    private String age = "222";
  }
}

public class AbstractTest {

  /**
   * 获取文件.
   *
   * @param name 文件名
   * @return 文件
   */
  public static File getResource(String name) {
    ClassLoader classLoader = AbstractTest.class.getClassLoader();
    File file = new File(classLoader.getResource(name).getFile());
    return file;
  }

  /**
   * 获取文件流.
   *
   * @param path 文件路径
   * @return 文件流
   */
  public static InputStream getResourceInput(String path) throws IOException {
    ClassLoader classLoader = AbstractTest.class.getClassLoader();
    return classLoader.getResource(path).openStream();
  }

  /**
   * 获取文件中的json.
   *
   * @param name 文件名
   * @author zhaona
   * @create 2018/5/29 11:50
   */
  public static String getJson(String name, String encoding) throws IOException {
    File file = getResource(name);
    String json = FileUtils.readFileToString(file, encoding);
    return json;
  }

  protected void periodicCheck(PassableRunnable runnable) throws InterruptedException {
    while (true) {
      runnable.run();
      if (runnable.isPassed()) {
        return;
      }
      TimeUnit.MILLISECONDS.sleep(50);
    }
  }

  public static interface PassableRunnable extends Runnable {
    boolean isPassed();
  }

  public void test(String str){
    System.out.println(str);
  }
}

zeal

一个喜欢安静,追求技术的全栈程序猿。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*