Day30---昨天周六休息一天

今晚大概率是不学习的晚上,有FPX比赛,3比0赢下的话,我8点应该可以去图书馆学习,希望3比0。还差后面一点内容了,下周本来想学数据库的相关操作,但是要先把Java基础先整体过一遍,做一个小项目,做出来后,再继续学数据库的内容。加油OVO

Day30

以下都是Java8的新特性

1.Lambda表达式

lambada匿名函数。

package com.sorrymaker.Lambda;

import org.junit.Test;

import java.util.Comparator;

public class LambdaTest {

   @Test
   public void test1(){
       //这里调用了lambda匿名函数
       Runnable r1 =()-> System.out.println("我是帅哥");
       r1.run();
  }

   @Test
   public void test(){
       Comparator<Integer> com1 =new Comparator<Integer>() {
           @Override
           public int compare(Integer o1, Integer o2) {
               return Integer.compare(o1,o2);
          }
      };
       int compare1 =com1.compare(11,21);
       System.out.println(compare1);
       System.out.println("==================");

       //Lambda表达式的写法
       Comparator<Integer> com2 =(o1,o2)->Integer.compare(o1,o2);
       int compare2 =com1.compare(11,21);
       System.out.println(compare2);

       System.out.println("==================");

       //方法引用
       Comparator<Integer> com3 =Integer::compare;
       int compare3 =com1.compare(22,11);
       System.out.println(compare3);
  }
}

2.函数式接口

package com.sorrymaker.Lambda;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
* Java内置的4大核心函数式接口
*
* 消费型接口 Consuerm<T>     void accept(T t)-->接受一个对象,不返回
* 供给型接口 Supplier<T>     T get()         -->返回类型为T的对象
* 函数型接口 Function<T,R>   R apply(T t)   -->接受一个T,返回一个R,
* 判断型接口 Predicate<T>   boolean test(T t)——>接受个类型T的对象,返回boolean值。
*
*/
public class LambdaTest2 {
   @Test
   public void test1(){
       //原来的写法:
       happytime(500, new Consumer<Double>() {
           @Override
           public void accept(Double aDouble) {
               System.out.println("学习真的好累。害~~钱为"+aDouble);
          }
      });

       System.out.println("========================");

       //现在这样子写
       happytime(400,money->System.out.println("学习真的好累。害~~钱为"+money));
  }
   public void happytime(double money, Consumer<Double> con){
       con.accept(money);
  }
   @Test
   public void test2(){
       List<String> list = Arrays.asList("北京","上害","广周","深正","北鼻","北边");
       List<String> filterStr = filterString(list, new Predicate<String>() {
           @Override
           public boolean test(String s) {
               return s.contains("上");
          }
      });
       System.out.println(filterStr);

       //更便捷的写方,java8的新特性。
       List<String> filterStr1 =filterString(list,s->s.contains("北"));

       System.out.println(filterStr1);
  }


   //根据给定的规则,过滤集合中的字符串,此规则由Predicate的方法决定。
   public List<String> filterString(List<String> list, Predicate<String> pre){

       ArrayList<String> filterList =new ArrayList<>();

       for(String str:list){
           if(pre.test(str)){
               filterList.add(str);
          }
      }
       return filterList;
  }
}

3.方法引用

package com.sorrymaker.Lambda;

import com.sorrymaker.TreeSetTest.Employee;
import com.sorrymaker.TreeSetTest.MyDate;
import org.junit.Test;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* 方法引用的使用
*
* 1.使用情景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
*
* 2.方法引用:本质上就是Lambda表达式,Lambda表达式作为函数式接口的实例,所以
*           方法引用,也就是函数接口的实例.
* 3.使用格式: 类(或对象) :: 方法名
*
* 4.具体分为如下的三种情况 :
*   对象 :: 非静态方法(实例方法)
*   类 :: 静态方法
*   类 :: 非静态方法
* (面向对象编程的时候,不能用类调用非静态方法.)
*
* 5.方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同。
*
*/
public class MethodRefTest {
   /**
    * 情况一:   对象 :: 实例方法
    * Consumer 中的 void accept(T t)
    * PrintStream 中的 void print(T t)
    */
   @Test
   public void test1() {
       Consumer<String> con1 = str -> System.out.println(str);
       con1.accept("北京");

       System.out.println("==========================");

       PrintStream ps = System.out;
       Consumer<String> con2 = ps::println;
       con2.accept("背景");
  }

   /**
    * Supplier中的T get()
    * Emplyoee中的String getName()
    */
   @Test
   public void test2() {
       Employee emp = new Employee("tom", 12, new MyDate(2000, 07, 25));
       Supplier<String> sup1 = () -> emp.getName();
       System.out.println(sup1.get());

       System.out.println("==========================");

       Supplier<String> sup2 = emp::getName;
       System.out.println(sup2.get());
  }

   /**
    * 情况二: 类 :: 静态方法
    * Comparator 中的int compare(T t1,T t2)
    * Integer中的int compare(T t1,T t2)
    */
   @Test
   public void test3() {
       Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1, t2);
       System.out.println(com1.compare(12, 21));

       System.out.println("==========================");

       //这里不用形参列表,因为和Comparator一样,所以不需要写。
       Comparator<Integer> com2 = Integer::compareTo;
       System.out.println(com2.compare(12, 11));

  }

   /**
    * Function中的R apply(T t)
    * Math中的Long round(Double d)
    */
   @Test
   public void test4() {
       Function<Double, Long> func = new Function<Double, Long>() {
           @Override
           public Long apply(Double d) {
               return Math.round(d);
          }
      };
       System.out.println("==========================");

       Function<Double, Long> func1 = d -> Math.round(d);
       System.out.println(func1.apply(12.3));
       System.out.println("==========================");

       Function<Double, Long> func2 = Math::round;
       System.out.println(func1.apply(12.6));

  }
   /**
    * 情况三: 类 :: 实例方法(很有难度)
    * Comparator 中的int compare (T t1,T t2)
    * String 中的int ti.compareTo(t2)
    */
   @Test
   public void test5(){
       Comparator<String> con1 =(s1,s2)->s1.compareTo(s2);
       System.out.println(con1.compare("abc", "abcdefg"));

       System.out.println("==========================");

       Comparator<String> con2 =String::compareTo;
       System.out.println(con2.compare("ac", "b"));
  }
   /**
    * BiPredicate中的boolean test(T t1,T t2);
    * String 中的boolean t1.equals(t2)
    */
   @Test
   public void test6(){
       BiPredicate<String,String> pre1 =(t1,t2)->t1.equals(t2);
       System.out.println(pre1.test("ab", "ab"));

       System.out.println("==========================");

       BiPredicate<String,String> pre2 =String::equals;
       System.out.println(pre2.test("abc", "abc"));
  }
   /**
    * Function中的R apply(T t)
    * Employee中的 String getName()
    */
   @Test
   public void  test7(){
       Employee employee = new Employee("tom",22,new MyDate(2000,01,02));
       Function<Employee,String> func1 =e->e.getName();
       System.out.println(func1.apply(employee));

       System.out.println("==========================");

       Function<Employee,String> func2 =Employee::getName;
       System.out.println(func2.apply(employee));
  }
}

4.构造器引用

package com.sorrymaker.Lambda;

import com.sorrymaker.TreeSetTest.Employee;
import org.junit.Test;

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

/**
* 一、构造器引用
*     跟方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
*     抽象方法的返回值类型即为构造器所属的类型。
*
* 二、数组引用
*     把数组看作是一个特殊的类,写法与构造器引用一致。
*/
public class ConstructorRefTest {
   //构造器引用
   //Supplier中的T get()
   //Empolyee的空参构造器和这个一模一样
   //   public Employee(){}.
   @Test
   public void test1(){
       Supplier<Employee> sup =new Supplier<Employee>() {
           @Override
           public Employee get() {
               return null;
          }
      };
       System.out.println("==========================");

       Supplier<Employee> sup1 =()->new Employee();

       System.out.println("==========================");

       Supplier<Employee> sup2 = Employee::new;

  }
   //Function 中的 R apply(T t)
   @Test
   public void test2(){
       Function<Integer,Employee> func1 = age ->new Employee(age);
       Employee employee =func1.apply(100);
       System.out.println(employee);

       System.out.println("==========================");

       Function<Integer,Employee> func2 =Employee::new;
       Employee employee1 = func2.apply(200);
       System.out.println(employee1);
  }
   //BiFunction中的R apply(T t,U u)
   @Test
   public void test3(){
       BiFunction<String,Integer,Employee> func1 =(name,age)->new Employee(name,age);
       System.out.println(func1.apply("Tom", 12));

       System.out.println("==========================");
       BiFunction<String,Integer,Employee> func2 =Employee::new;
       System.out.println(func2.apply("Tom", 11));
  }
   /**
    * 数组引用
    * Function中的 R apply(T t)
    */
   @Test
   public void test4(){
       Function<Integer,String[]> func1 = Length->new String[Length];
       String[] arr1 = func1.apply(5);
       System.out.println(Arrays.toString(arr1));

       System.out.println("==========================");
       Function<Integer,String[]> func2 =String[]::new;
       String[] arr2 = func2.apply(2);
       System.out.println(Arrays.toString(arr2));

  }
}

 

Stream API

1.创建Stream

package com.sorrymaker.Lambda;

import com.sorrymaker.TreeSetTest.Employee;
import com.sorrymaker.TreeSetTest.MyDate;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
* 1. Stream关注的式对数据的运算,与CPU打交道。
*   集合关注的式数据的存储,与内存打交道。
*
* 2.
*   -1.Stream 自己不会存储元素
*   -2.Stream 不会改变源对象,相反,他们会返回一个持有结果的新Stream。
*   -3.Stream 操作时延迟执行的。这意味着他们会等到需要结果的时候才执行
*
* 3.Stream 执行流程
*   Stream 的实例化
*   一系列的中间操作(过滤,映射...)
*   终止操作
*
* 4.说明
*   4.1 一个中间操作链,对数据源的数据进行处理
*   4.2 一旦执行终止操作,就执行中间操作链,并产生结果,之后,不会在再被使用。
*/
public class StreamAPITest {
   //创建Stream方式一:通过集合
   @Test
   public void test1(){
       List<Employee> employees =EmployeeData.getEmplyoees();

       //返回一个顺序流
       Stream<Employee> stream =employees.stream();

       //返回一个并行流
       Stream<Employee> parallelStream =employees.parallelStream();
  }
   //创建Stream方式二:通过数组
   @Test
   public void test2(){
       //调用Arrays类的
       int[] arr =new int[]{1,2,3,4,5,6};
       IntStream stream = Arrays.stream(arr);

       Employee e1 =new Employee("TT",12,new MyDate(199,20,1));
       Employee e2 =new Employee("Tian",13,new MyDate(199,20,1));
       Employee[] arr1 = new Employee[]{e1,e2};
       Stream<Employee> stream1 = Arrays.stream(arr1);

  }
   //创建Stream方式三:通过Stream的of()
   @Test
   public void test3(){
       //这里提供的是T,不是int型,是包装类
       Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7);
  }

   @Test
   //创建Stream方式四:创建无限流
   public void test4(){
       //迭代
       //public static<T> Stream<T> iterate(final T seed,final UnaryOperator<T> f)
       //遍历前10个偶数
       Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);

       //生成
       //public static<T> Stream<T> generate(Supplier<T> s)
       Stream.generate(Math::random).limit(10).forEach(System.out::println);
  }
}

2.Stream中间的操作

---映射

package com.sorrymaker.Lambda;

import com.sorrymaker.TreeSetTest.Employee;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
* 测试Stream的中间操作
*/
public class StreamAPITest1 {
   //1.筛选和切片
   @Test
   public void test1(){
       List<Employee> list = EmployeeData.getEmplyoees();

       Stream<Employee> stream  = list.stream();
       //filter(Predicate p) ——接受Lambda。从流中排除某些元素。
       //练习:查询员工表中年龄小于13的员工数量。
       stream.filter(e ->e.getAge()<50).forEach(System.out::println);

       //每当流执行完后,需要重新创建流,不然会报错了。
       System.out.println();

       //Limit(n) ——截断流:使其元素不超过给定数量。
       list.stream().limit(3).forEach(System.out::println);

       System.out.println();

       //skip(n) ——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流
       list.stream().skip(3).forEach(System.out::println);

       System.out.println();

       //distinct() ——筛选,通过流所生成的元素的hashCode() 和 equals() 去除重复元素。

       list.stream().distinct().forEach(System.out::println);
  }

   //映射
   @Test
   public void test2(){
       /**
        * map(Function f) --接受一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素,并将其映射成一个新元素
        */
       List<String> list = Arrays.asList("aa", "bb", "cc", "dd", "ee");
       //将这些元素,转换成其他形式,获得新元素。
       list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
       //获取员工姓名长度大于3的姓名
       List<Employee> list1 = EmployeeData.getEmplyoees();

       //这里还可以这样子写,都一样。
       //Stream<String> nameStream = list1.stream().map(e -> e.getName());
       Stream<String> nameStream = list1.stream().map(Employee::getName);

       //练习1:获取员工名字长度大于3的姓名。过滤
       nameStream.filter(name->name.length()>3).forEach(System.out::println);

       System.out.println();
       //练习2:
       //Stream里有个Stream。用flatMap在这种情况下,比map好用。
       Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest1::fromStringToStream);
       streamStream.forEach(s->{
           s.forEach(System.out::println);
      });
       System.out.println();

       //flatMap(Function f)--接受一个函数作为参数,将流中的每个值转换为另一个流,然后把所有的流连成一个流
       //list.add和map类似---加一个流。
       //list.addAll和flatMap类似---把一个流打散,然后合并成一个大流。

       Stream<Character> characterStream = list.stream().flatMap(StreamAPITest1::fromStringToStream);
       characterStream.forEach(System.out::println);
  }

   //将字符串中的多个字符构成的集合转换为对应Stream的实例。
   public  static Stream<Character> fromStringToStream(String str){
       ArrayList<Character> list =new ArrayList<>();
       for(Character c:str.toCharArray()){
           list.add(c);
      }
       return list.stream();
  }

   @Test
   public void test3(){
       ArrayList list1 =new ArrayList<>();
       list1.add(1);
       list1.add(2);
       list1.add(3);

       ArrayList list2 = new ArrayList();
       list2.add(4);
       list2.add(5);
       list2.add(6);
       //list.add 和 list.addAll的区别,跟上面一个道理
       list1.addAll(list2);
       System.out.println(list1);
  }
}

---终止操作

package com.sorrymaker.Lambda;

import com.sorrymaker.TreeSetTest.Employee;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Stream终止操作
*/
public class StreamTest1 {
   //1.匹配与查找
   @Test
   public void test1(){
       List<Employee> emplyoees = EmployeeData.getEmplyoees();
       //allMath(Predicate p)--检查是否匹配所有元素
       boolean allMath = emplyoees.stream().allMatch(e -> e.getAge() > 18);
       System.out.println(allMath);

       //anyMath(Predicate p)--检查是否至少匹配一个元素。
       boolean anyMath = emplyoees.stream().anyMatch(e -> e.getAge() > 15);
       System.out.println(anyMath);

       //noneMath(Predicate p)--检查是否没有匹配的元素
       boolean noneMath = emplyoees.stream().noneMatch(e -> e.getName().contains("jarry"));
       System.out.println(noneMath);

       //findFirst --返回第一个元素
       Optional<Employee> employee = emplyoees.stream().findFirst();
       System.out.println(employee);

       //findAny --返回当前流的中的任意元素
       //parallelStream()并行流,不会总是从第一个取。
       Optional<Employee> employee1 = emplyoees.parallelStream().findAny();
       System.out.println(employee1);

  }

   @Test
   public void test2(){
       //count--返回流的元素的总个数
       List<Employee> emplyoees = EmployeeData.getEmplyoees();
       long count = emplyoees.stream().filter(e -> e.getAge() < 15).count();
       System.out.println(count);

       //max(Comparator c)--返回流中最大值,返回年龄最大的值
       Stream<Integer> integerStream = emplyoees.stream().map(Employee::getAge);
       Optional<Integer> max = integerStream.max(Integer::compare);
       System.out.println(max);

       //min(Comparator c)--返回流中最小值
       Optional<Employee> min = emplyoees.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
       System.out.println(min);

       //forEach(Consumer c)--内部迭代。
       emplyoees.stream().forEach(System.out::println);

       //使用集合的内部迭代。
       emplyoees.forEach(System.out::println);
  }
   //2-归约
   @Test
   public void test3(){
       //reduce(T identity,BinaryOperator)-可以将流中元素反复结合起来,得到一个值,返回T
       //练习一:计算1-10的自然数的和
       List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
       Integer sum = list.stream().reduce(0, Integer::sum);
       System.out.println(sum);

       //reduce(BinaryOperator) --可以将流 中元素反复结合起来,得到一个值,返回Optional<T>
       //计算所有员工的岁数
       List<Employee> emplyoees = EmployeeData.getEmplyoees();
       Stream<Integer> ageSum = emplyoees.stream().map(e -> e.getAge());
       Optional<Integer> sumAge = ageSum.reduce(Integer::sum);
       System.out.println(sumAge);
  }
   //3-收集
   @Test
   public void test4(){
       //collect(Collector c)--将流转换为其他形式,接受一个Collector接口的实现,
       //1.查找年龄大于14的员工,结果返回一个List或Set

       List<Employee> emplyoees = EmployeeData.getEmplyoees();
       List<Employee> employeeList = emplyoees.stream().filter(e -> e.getAge() > 14).collect(Collectors.toList());
       employeeList.forEach(System.out::println);
       System.out.println();

       Set<Employee> employeeSet = emplyoees.stream().filter(e -> e.getAge() > 13).collect(Collectors.toSet());
       employeeSet.forEach(System.out::println);

       //toCollection.
  }
}

 

posted @ 2021-04-11 16:25  独眼龙  阅读(124)  评论(0)    收藏  举报