一、lambda
主要解决匿名内部方法问题
1.可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 2.可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。 3.可选的大括号:如果主体包含了一个语句,就不需要使用大括号。 4.可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。 表达式如下: parameter -> expression或(parameters) -> expression或(parameters) ->{statements; }
demo如下:
List<Integer> list = new ArrayList<>();
list.add(1111);
list.add(2222);
list.add(4444);
list.add(3333);
list.add(5555);
//TODO jdk7
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
for (Integer s: list) {
System.out.println(s);
}
//TODO jdk8
Collections.sort(list,(s1,s2) -> {return s1.compareTo(s2);});//多个参数需要括号,如果方法主体只有一个表达式返回值
Collections.sort(list,(s1,s2) -> s1.compareTo(s2));//多个参数需要括号,如果方法主体只有一个表达式返回值,不需要return关键字
list.forEach(s -> System.out.println(s));//一个参数不需要括号
二、引用
方法引用通过方法的名字来指向一个方法。 方法引用可以使语言的构造更紧凑简洁,减少冗余代码。 方法引用使用一对冒号 :: 。
以下初略的对比了引用和lambda的区别
User user = new User();
user.setName("zhong");
user.setAge(11);
User user1 = new User();
user1.setName("da");
user1.setAge(12);
User user2 = new User();
user2.setName("xiao");
user2.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
//lambda
List<User> lambda = list.stream().sorted(Comparator.comparing(e -> e.getAge())).collect(Collectors.toList());
lambda.forEach(e -> System.out.println(e.getName()));
list.forEach(e -> System.out.println(e.getName()));
//引用
List<User> quote = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
quote.forEach(e -> System.out.println(e.getName()));
三、Optional
optional的创建方法如下两种分别为:Optional.of(T)和Optional.ofNullable(T)
public static <T> Optional<T> of(T value):value的值不能为null----Optional.of(T)
public static <T> Optional<T> ofNullable(T value):value允许为空----Optional.ofNullable(T)
Optional常用方法是对对象的过滤和map操作,demo如下
过滤
User user = new User("ljyy",22);
User user2 = Optional.ofNullable(user).filter(u -> u.getAge()>30).orElse(new User("chenjiabing",30));
System.out.println(user2);
map
User user = new User("chenjiabing",22);
Optional.ofNullable(user).map(e -> {
e.setAge(23);
return e;
});
System.out.println(user.getAge());
Stream
stream的大概主要方法如下
filter():对流的元素过滤
map():将流的元素映射成另一个类型
distinct():去除流中重复的元素
sorted():对流的元素排序
forEach():对流中的每个元素执行某个操作
peek():与forEach()方法效果类似,不同的是,该方法会返回一个新的流,而forEach()无返回
limit():截取流中前面几个元素
skip():跳过流中前面几个元素
toArray():将流转换为数组
reduce():对流中的元素归约操作,将每个元素合起来形成一个新的值
collect():对流的汇总操作,比如输出成List集合
anyMatch():匹配流中的元素,类似的操作还有allMatch()和noneMatch()方法
findFirst():查找第一个元素,类似的还有findAny()方法
max():求最大值
min():求最小值
Filter过滤
* 过滤集合,实际是实现其中的test方法, * 返回的是一个Boolean类型的值, * 我们可以使用lambda表达式可以很轻松的实现集合的过滤
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
List<User> collect = list.stream().filter(u -> {
if(u.getAge() >10){
return true;
}
return false;
}).collect(Collectors.toList());
collect.forEach(u -> System.out.println(u.getName()));
sorted排序
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
List<User> collect1 =list.stream().sorted((e1,e2) -> e1.getAge().compareTo(e2.getAge())).collect(Collectors.toList());
System.out.print("自动定义排序:");
collect1.forEach( e -> System.out.print(e.getAge()+" "));
System.out.println("");
List<User> collect2 =list.stream().sorted(Comparator.comparing(e->e.getAge())).collect(Collectors.toList());
System.out.print("Comparator lambda方式排序:");
collect2.forEach( e -> System.out.print(e.getAge()+" "));
System.out.println("");
List<User> collect3 =list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
System.out.print("Comparator 引用方式排序:");
collect3.forEach( e -> System.out.print(e.getAge()+" "));
System.out.println("");
List<User> collect4 =list.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
System.out.print("倒序:");
collect4.forEach( e -> System.out.print(e.getAge()+" "));
Match查询
// 检查流中的任意元素是否包含字符串"Java"
boolean hasMatch = Stream.of("Java", "C#", "PHP", "C++", "Python").anyMatch(e -> e.equals("Java"));
// 检查流中的所有元素是否都包含字符串"#"
boolean hasAllMatch = Stream.of("Java", "C#", "PHP", "C++", "Python").allMatch(s -> s.contains("#"));
// 检查流中的任意元素是否没有以"C"开头的字符串
boolean hasNoneMatch = Stream.of("Java", "C#", "PHP", "C++", "Python").noneMatch(s -> s.startsWith("C"));
// 查找元素
Optional<String> element = Stream.of("Java", "C#", "PHP", "C++", "Python")
.filter(s -> s.contains("C"))
// .findFirst() // 查找第一个元素
.findAny(); // 查找任意元素
map操作(将每个人的年龄*2)
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
//对list每个元素操作
List<User> collect = list.stream().map(item -> {
item.setAge(item.getAge() * 2);
return item;
}).collect(Collectors.toList());
collect.forEach( e -> System.out.println(e.getAge()));
reduce归约(算出三个人的年龄之和)
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
Optional<Integer> optional = list.stream().map(item -> item.getAge()).reduce((item1, item2) -> item1 + item2);
if (optional.isPresent()){
System.out.println(optional.get());
}
groupby分组
//根据字段分组(根据年龄字段分组)
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
User user3 = new User();
user3.setName("liuli");
user3.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
list.add(user3);
//根据age进行分组,返回的是Map集合,key就是分组后的age,value是user对象
Map<Integer, List<User>> listMap = list.parallelStream().collect(Collectors.groupingBy(item -> item.getAge()));
listMap.forEach((key,value)->{
System.out.println(key+"--->"+value);
});
//根据条件分组(年龄大于10岁为A组,其他的为B组)
User user = new User();
user.setName("lili");
user.setAge(11);
User user1 = new User();
user1.setName("wangli");
user1.setAge(12);
User user2 = new User();
user2.setName("hanli");
user2.setAge(10);
User user3 = new User();
user3.setName("liuli");
user3.setAge(10);
List<User> list = new ArrayList<>();
list.add(user);
list.add(user1);
list.add(user2);
list.add(user3);
//根据age进行分组,返回的是Map集合,key就是分组后的age,value是user对象
Map<String, List<User>> listMap = list.parallelStream().collect(Collectors.groupingBy(item -> {
if (item.getAge() > 10) {
return "A";
} else {
return "B";
}
}));
listMap.forEach((key,value)->{
System.out.println(key+"--->"+value);
});