前言

jdk8增加了很多东西,大致分为以下几种吧(这里重点说下Lambda表达式和Stream API)

  • Lambda表达式
  • 函数式接口
  • 方法引用和构造器调用
  • Stream API
  • 接口中的默认方法和静态方法
  • 新时间日期API

一、Stream Api

1、Stream 特点

①Stream 自己不会存储元素。 ②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。 ③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

2、执行过程

2.1、Stream的实例化

2.2、一系列的中间操作(过滤、映射、…)

一个中间操作链,对数据源的数据进行处理

3、终止操作

一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用。一旦结束了,想要再次使用,就必须重新再造。 必须要有终止操作,才会执行中间操作。

4、创建方式

//创建 Stream方式一:通过集合 // default Stream<E> stream() : 返回一个顺序流 Stream<Employee> stream = employees.stream();//employees是一个集合

// default Stream<E> parallelStream() : 返回一个并行流 Stream<Employee> parallelStream = employees.parallelStream();

//创建 Stream方式二:通过数组 int[] arr = new int[]{1,2,3,4,5,6}; //调用Arrays类的static <T> Stream<T> stream(T[] array): 返回一个流 IntStream stream = Arrays.stream(arr);//返回类型我IntStream

Employee e1 = new Employee(1001,”Tom”); Employee e2 = new Employee(1002,”Jerry”); Employee[] arr1 = new Employee[]{e1,e2}; Stream<Employee> stream1 = Arrays.stream(arr1);

//创建 Stream方式三:通过Stream的of() Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

//创建 Stream方式四:创建无限流 用的比较少

// 迭代 // public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) //遍历前10个偶数,iterate: Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);//limit终止操作,只输出10个值

// 生成 // public static<T> Stream<T> generate(Supplier<T> s) Stream.generate(Math::random).limit(10).forEach(System.out::println); //输出10个随机数

5、实战记录

个人觉得每学一个知识点,还是只有多去实战才能学得更好

public class EmployeeData {   
public static List<Employee> getEmployees(){  
List<Employee> list = new ArrayList<>(); 
list.add(new Employee(1001, "马化腾", 34, 6000.38)); 
list.add(new Employee(1002, "马云", 12, 9876.12)); 
list.add(new Employee(1003, "刘强东", 33, 3000.82));  
list.add(new Employee(1004, "雷军", 26, 7657.37)); 
list.add(new Employee(1005, "李彦宏", 65, 5555.32));    
list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));  
list.add(new Employee(1007, "任正非", 26, 4333.32));  
list.add(new Employee(1008, "扎克伯格", 35, 2500.32));  
return list;
}}
List<Employee> list = EmployeeData.getEmployees();//  
filter(Predicate p)——接收 Lambda , 从流中排除某些元素。   
Stream<Employee> stream = list.stream();  
//练习:查询员工表中薪资大于7000的员工信息     
stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);        System.out.println();//    
skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补    
list.stream().skip(3).forEach(System.out::println);
//跳过前面三个数据System.out.println();
//     
distinct()——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素    
list.add(new Employee(1010,"刘强东",40,8000));      
list.add(new Employee(1010,"刘强东",41,8000));       
list.add(new Employee(1010,"刘强东",40,8000));    
list.add(new Employee(1010,"刘强东",40,8000));    
list.add(new Employee(1010,"刘强东",40,8000));// 
System.out.println(list); 
list.stream().distinct().forEach(System.out::println);

映射:

//
map(Function f)——接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。   
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");  
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println); 
//map会把list里面的每个元素取出来,自动会有一个遍历,每一个元素字母变为大写,然后返回一个str

排序

//3-排序  
  @Test    
  public void test4(){//    
  sorted()——自然排序      
  List<Integer> list = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);        list.stream().sorted().forEach(System.out::println);   
  //抛异常,原因:Employee没有实现Comparable接口//    
  List<Employee> employees = EmployeeData.getEmployees();//        employees.stream().sorted().forEach(System.out::println);//   
  sorted(Comparator com)——定制排序   
  List<Employee> employees = EmployeeData.getEmployees();        employees.stream().sorted( (e1,e2) -> {       
  int ageValue = Integer.compare(e1.getAge(),e2.getAge());     
  if(ageValue != 0){     
  return ageValue;    
  }else{             
  return -Double.compare(e1.getSalary(),e2.getSalary());   
  }     
  }).forEach(System.out::println);  
  }

二、Lambda表达式

1、为什么使用Lambda

  • 在Java中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法, 也无法声明返回一个函数的方法,
  • 在JavaScript中,函数参数是一个函数,返回值是 另一个函数的情况是非常常见的; JavaScript是-门非常典型的函数式语言.

2、Lambda表达式作用

  • Lambda表达式为Java添加了缺失的函数式编程特性,使我们能将函数当做一等公民看待
  • 在将函数作为一等公民的语言中,Lambda表达式的类型是函数。但在Java中,Lambda表达式是对象,他们必须依附于一类特别的对象类型———>函数式接口(functional interface).

3、匿名内部类(例子)

3.1、以前的书写

public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(i);
                }
            }
        });
    }

3.2.使用Lambda表达式

 public static void main(String[] args) {
        new  Thread(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println(i);
            }
        });
    }

4、Lambda表达式格式

4.1、简介

(参数列表) -> {}
(参数列表): 参数列表,可有可无
{}: 方体体
->: 没有实际意义起到连接作用

4.2、无参无返回值

@FunctionalInterface
interface MyInterFace1 {
    void test1();
}
public class Test2 {
    public static void main(String[] args) {
        fun1(()->{
            System.out.println("-----------------方法执行了---------------");
        });
    }
    public static void fun1(MyInterFace1 myInterFace) {
        myInterFace.test1();
    }
}

4.3、一个参数无返回值

@FunctionalInterface
interface MyInterFace {
    void test1(String name);
}
public class Test2 {
    public static void main(String[] args) {
           //这里的参数都是自定义的,只是这样写代码看起来更舒服
        fun1((String name)->{
            System.out.println("------------方法执行了----------"+name);
        });
        //可以不指定类型
        fun1((name)->{
            System.out.println("------------方法执行了----------"+name);
        });
        //可以省略写
        fun1(name->{
            System.out.println("------------方法执行了----------"+name);
        });
    }
    public static void fun1(MyInterFace myInterFace) {
        myInterFace.test1("admin");
    }
}

4.4、多个参数无返回值

@FunctionalInterface
interface MyInterFace {
    void test1(String name,int age,Double price);
}
public class Test2 {
    public static void main(String[] args) {
        //这里的参数都是自定义的,只是这样写代码看起来更舒服
        fun1((name,age,price) -> {
            System.out.println(name+"===="+age+"===="+price);
        });
    }
    public static void fun1(MyInterFace myInterFace) {
        myInterFace.test1("admin",10,20D);
    }
}

4.5、一个参数有返回值

@FunctionalInterface
interface MyInterFace {
    String test1(String name);
}
public class Test2 {
    public static void main(String[] args) {
        fun1(name -> {
           return name;
        });
    }
    public static void fun1(MyInterFace myInterFace) {
        myInterFace.test1("admin");
    }
}

4.6、多个参数切有返回值

@FunctionalInterface
interface MyInterFace {
    String test1(String name,String name2);
}
public class Test2 {
    public static void main(String[] args) {
        fun1((name,name2) -> {
           return name+name2;
        });
    }
    public static void fun1(MyInterFace myInterFace) {
        System.out.println(myInterFace.test1("admin", "sd"));
    }
}

5、Stream和Lambda简单测试

public static void main(String[] args) {
    ArrayList<User> list = new ArrayList<>();
    for (int i=0;i<=10;i++){
        User user=new User();
        user.setId(1l);
        user.setUsername("张三"+i);
        user.setPassword("123");
        list.add(user);
    }
    list.stream().forEach(e-> System.out.println(e.getUsername()));
}

 

推荐阅读

汇智知了堂:SpringBoot整合Druid

汇智知了堂:开发神器EasyCode

汇智知了堂:百度地图接口实现添加坐标点和路线

汇智知了堂:SpringBoot整合QQ邮件发送

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐