Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
() -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。
//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
NoReturnMultiParam lamdba1 = (a, b) -> {
System.out.println("简化参数类型");
};
lamdba1.method(1, 2);
//2.简化参数小括号,如果只有一个参数则可以省略参数小括号
NoReturnOneParam lambda2 = a -> {
System.out.println("简化参数小括号");
};
lambda2.method(1);
//3.简化方法体大括号,如果方法条只有一条语句,则可以省略方法体大括号
NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
lambda3.method();
//4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
ReturnOneParam lambda4 = a -> a + 3;
System.out.println(lambda4.method(5));
ReturnMultiParam lambda5 = (a, b) -> a + b;
System.out.println(lambda5.method(1, 1));
@FunctionalInterface // 函数式接口 , 标识着只能有一个需要被实现的方法 。
有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。
语法 : 方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象或者this。
如果时构造方法的引用 通过 类名::new 的方式来实现。
要求:
1.参数数量和类型要与接口中定义的一致
2.返回值类型要与接口中定义的一致
3.构造的方法引用同上
returnOneParam lambda1 = a -> doubleNum(a); // ==
//lambda2 引用了已经实现的静态 doubleNum 方法
ReturnOneParam lambda2 = Exe1::doubleNum;
//lambda4 引用了已经实现的非静态 addTwo 方法
ReturnOneParam lambda4 = exe::addTwo;
ItemCreatorBlankConstruct creator = () -> new Item();
ItemCreatorBlankConstruct creator2 = Item::new;
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 1,2,3,4,5);
//lambda表达式 方法引用
list.forEach(System.out::println);
ArrayList<Item> items = new ArrayList<>();
items.add(new Item(11, "小牙刷", 12.05 ));
items.add(new Item(5, "日本马桶盖", 999.05 ));
items.add(new Item(7, "格力空调", 888.88 ));
items.add(new Item(17, "肥皂", 2.00 ));
items.add(new Item(9, "冰箱", 4200.00 ));
// 删除Item 对象中 id = 7 。
items.removeIf(ele -> ele.getId() == 7);
//通过 foreach 遍历,查看是否已经删除
items.forEach(System.out::println);
在以前我们若要为集合内的元素排序,就必须调用 sort 方法,传入比较器匿名内部类重写 compare 方法,我们现在可以使用 lambda 表达式来简化代码
ArrayList<Item> list = new ArrayList<>();
list.add(new Item(13, "背心", 7.80));
list.add(new Item(11, "半袖", 37.80));
list.add(new Item(14, "风衣", 139.80));
list.add(new Item(12, "秋裤", 55.33));
/*
list.sort(new Comparator- () {
@Override
public int compare(Item o1, Item o2) {
return o1.getId() - o2.getId();
}
});
*/
// 升序: 排序
list.sort((o1, o2) -> o1.getId() - o2.getId());
System.out.println(list);
Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。
Stream可以由数组或集合创建,对流的操作分为两种:
中间操作,每次返回一个新的流,可以有多个
终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。
stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
stream不会改变数据源,通常情况下会产生一个新的集合或一个值
stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行
Stream可以通过集合数组创建。
1、通过 java.util.Collection.stream() 方法用集合创建流
2、使用java.util.Arrays.stream(T[] array)方法用数组创建流
3、使用Stream的静态方法:of()、iterate()、generate()
public class StreamCreateType {
public static void main(String[] args) {
//1. Collection.stream()方法用集合创建
List<String> list = Arrays.asList("1","2","3");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> stringStream = list.parallelStream();
List<String> collect = stringStream.collect(Collectors.toList());
//2. Arrays.stream(T[] array) 方法用数组创建
int[] array={1,2,3,4,5};
IntStream stream1 = Arrays.stream(array);
System.out.println(stream1.max().getAsInt());
//3. 使用Stream的静态方法:of()、iterate()、generate()
Stream<Integer> intStream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
// 0 3 6 9
stream2.forEach(System.out::println);
AtomicInteger m = new AtomicInteger(10);
Stream<Integer> stream3 = Stream.generate(()-> m.getAndIncrement()).limit(3);
//10 11 12
stream3.forEach(System.out::println);
}
}
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
//1. 顺序遍历
list.forEach(System.out::println);
System.out.println("=====================");
//筛选出Integer集合中大于7的元素,并打印出来 filter 筛选
List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2, 9);
Stream<Integer> stream = list.stream();
stream.filter(x -> x > 7)..collect(Collectors.toList()).forEach(System.out::println);
List<Item> collect = items.stream().filter(item -> item.id > 7).collect(Collectors.toList());
// 找出数字的最大值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Integer integer = list.stream().max(((o1, o2) -> o1 - o2)).get();
System.out.println("integer = " + integer);
// 找出最长的字符串
List<String> myList = Arrays.asList("李磊", "韩梅梅", "Lucy", "Jim");
String s = myList.stream().max(((o1, o2) -> o1.length() - o2.length())).get();
System.out.println("s = " + s);
//4 . 计算Integer集合中大于6的元素的个数
List<Integer> list4 = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
long count = list4.stream().filter(x -> x > 6).count();
System.out.println("list中大于6的元素个数:" + count);
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
//1. 英文字符串数组的元素全部改为大写。
String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
List<String> strList1 = Arrays.stream(strArr).map(str -> str.toUpperCase()).collect(Collectors.toList());
//整数数组每个元素+3。
List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);
List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println("每个元素+3:" + intListNew);
// 取名字 成一个
ArrayList<Item> items = new ArrayList<>();
items.add(new Item(11, "小牙刷", 12.05));
items.add(new Item(5, "日本马桶盖", 999.05));
items.add(new Item(7, "格力空调", 888.88));
items.add(new Item(17, "肥皂", 2.00));
items.add(new Item(9, "冰箱", 4200.00));
List<String> collect = items.stream()
.map(item -> item.name)
.collect(Collectors.toList());
collect.forEach(System.out::println);
//1. 求Integer集合的元素之和、乘积和最大值
List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
// 求和方式1
Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
// 求乘积
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
// 求最大值方式1
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
// 求工资之和方式1:
Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);
// 收集
collect(Collectors.toList());
collect(Collectors.toSet());
统计:
Collectors提供了一系列用于数据统计的静态方法:
计数:count
平均值:averagingInt、averagingLong、averagingDouble
最值:maxBy、minBy
求和:summingInt、summingLong、summingDouble
统计以上所有:summarizingInt、summarizingLong、summarizingDouble
list.add(new Person("张三", 3000, 23, "男", "武汉"));
list.add(new Person("李四", 4000, 24, "男", "合肥"));
list.add(new Person("王五", 5000, 25, "女", "武汉"));
list.add(new Person("赵六", 6000, 26, "男", "北京"));
list.add(new Person("田七", 7000, 27, "女", "北京"));
list.add(new Person("王八", 8000, 28, "男", "武汉"));
// 球总数
Long count = list.stream().collect(Collectors.counting());
System.out.println(count);
// 求平均
Double avg = list.stream().collect(Collectors.averagingDouble(Person::getSalary));
System.out.println(avg);
// 求最高工资
Person person = list.stream().collect(Collectors.maxBy(((o1, o2) -> o1.getSalary() - o2.getSalary()))).get();
System.out.println(person);
// 求工资之和
Integer sum = list.stream().collect(Collectors.summingInt(Person::getSalary));
System.out.println(sum);
// 统计以上所有信息
DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println(collect);
分组
/**
* 分组
* @param args
*/
public static void main8(String[] args) {
Map<String, List<Person>> listMap = list.stream().collect(Collectors.groupingBy(Person::getSex));
for (Map.Entry<String, List<Person>> entry : listMap.entrySet()) {
System.out.println(entry.getKey());
List<Person> list1 = entry.getValue();
list1.forEach(System.out::println);
}
System.out.println("=================================================================");
Map<String, List<Person>> listMap1 = list.stream().collect(Collectors.groupingBy(Person::getArea));
for (Map.Entry<String, List<Person>> entry : listMap1.entrySet()) {
System.out.println(entry.getKey());
List<Person> list1 = entry.getValue();
list1.forEach(System.out::println);
}
System.out.println("=================================================================");
Map<String, Map<String, List<Person>>> map = list.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
String s = JSON.toJSONString(map);
System.out.println(s);
}
/**
* 接合 ( 按照 , 进行拼接)
* @param args
*/
public static void main9(String[] args) {
String s = list.stream().map(Person::getName).collect(Collectors.joining(","));
System.out.println(s);
}
sorted,中间操作。有两种排序:
1. sorted():自然排序,流中元素需实现Comparable接口
2. sorted(Comparator com):Comparator排序器自定义排序
/**
* 排序
* @param args
*/
public static void main10(String[] args) {
List<Person> list = Demo4.list.stream().sorted(((o1, o2) -> o2.getSalary() - o1.getSalary())).collect(Collectors.toList());
list.forEach(System.out::println);
}
流也可以进行合并、去重、限制、跳过等操作。
List<String> list1 = Arrays.asList("a", "b", "c", "d", "e");
List<String> list2 = Arrays.asList("d", "e", "f", "g");
Stream<String> stream1 = list1.stream();
Stream<String> stream2 = list2.stream();
// 合并流 + 去重操作
List<String> list3 = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
List<Integer> list4 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
// limit 为取 10 条数据
List<Integer> list5 = list4.stream().limit(10).collect(Collectors.toList());
System.out.println(list5);
// skip 为跳过 5 条数据 取10条数据
List<Integer> list6 = list4.stream().skip(5).limit(10).collect(Collectors.toList());
System.out.println(list6);