Jdk8新特性(Stream、Lambda表达式)
前言jdk8增加了很多东西,大致分为以下几种吧(这里重点说下Lambda表达式和Stream API)Lambda表达式函数式接口方法引用和构造器调用Stream API接口中的默认方法和静态方法新时间日期API一、Stream Api1、Stream 特点①Stream 自己不会存储元素。 ②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。 ③Stream 操作是延迟
前言
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()));
}
推荐阅读
更多推荐
所有评论(0)