本文记录Javalambda表达式使用过程中,能很优雅解决的问题的一些实践,持续更新。
1、匿名内部类使用
new Thread(() -> System.out.println("This is a Thread")).start();
Runnable runnable = () -> System.out.println("This is a thread");
new Thread(runnable).start();
如果是有参数:
(int even, int odd) -> even + odd
B c = (a, b) -> System.out.println(a+b);
c.test(1,2);
2、使用lamba表达式对列表进行迭代
list.forEach(l -> System.out.println(l));
跳出本次循环 使用 return; forEach不是循环,不能使用continue
3、方法引用排序
Arrays.asList(str).sort((a, b) -> a.compareTo(b));
Arrays.asList(str).sort(String::compareTo);
4、predicate操作 filter 过滤
Predicate<String> startsWithJ = (n) -> n.startsWith("J");
Predicate<String> fourLetterLong = (n) -> n.length() == 4;
names.stream()
.filter(startsWithJ.and(fourLetterLong))
.forEach((n) -> System.out.print("nName, which starts with 'J' and four letter long is : " + n));
5、Map操作 操作集合数据 k将结果进行处理等
List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
costBeforeTax.stream().map((cost) -> cost + 0.12 * cost).forEach(System.out::println);
6、reduce操作 求和 average()、count()、sum()
List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get();
System.out.println("Total : " + bill);
7、通过过滤创建一个String列表 collect(Collectors.toList());
List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);
8、对列表的每个元素应用函数collect(Collectors.joining(", "));
// 将字符串换成大写并用逗号链接起来
List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada");
String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
System.out.println(G7Countries);
9、复制不同的值,创建一个子列表,去重 distinct
List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
List<Integer> distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
System.out.printf("Original List : %s, Square Without duplicates : %s %n", numbers, distinct);
10、List<String> 拼接方法 java8
public static String formatList(List<String> list, String delimiter) {
return String.join(delimiter, list);
}
11、将list 转换为Map
常用方式
代码如下:
public Map<Long, String> getIdNameMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getUsername));
}
收集成实体本身map
代码如下:
public Map<Long, Account> getIdAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, account -> account));
}
account -> account是一个返回本身的lambda表达式,其实还可以使用Function接口中的一个默认方法代替,使整个方法更简洁优雅:
public Map<Long, Account> getIdAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity()));
}
重复key的情况
代码如下:
public Map<String, Account> getNameAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity()));
}
这个方法可能报错(java.lang.IllegalStateException: Duplicate key),因为name是有可能重复的。toMap有个重载方法,可以传入一个合并的函数来解决key冲突问题:
public Map<String, Account> getNameAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -> key2));
}
这里只是简单的使用后者覆盖前者来解决key重复问题。
指定具体收集的map
toMap还有另一个重载方法,可以指定一个Map的具体实现,来收集数据:
public Map<String, Account> getNameAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));
}
//toMap 重复KEY会抛出异常
java.lang.IllegalStateException: Duplicate key 2816
解决:
areaList.stream().collect(Collectors.toMap(VenderReceiveAreaVO::getCountyId, VenderReceiveAreaVO::getCountyId, (oldKey, newKey) -> newKey))
12、结果集合并,再处理,List<List> 这样的接口可用使用flatMap处理
List<QualifiVo> qualifiVos = qualifications.stream().map(QualificationScopeDTO::getVenderQualification)
//过滤为空的数据
.filter(StringUtils::isNotBlank)
//处理数据
.map(venderQualifi -> Arrays.asList(venderQualifi.split(",")))
//list 合并
.flatMap(Collection::stream)
//将type转换为QualifEnum
.map(type -> QualifEnum.queryBuyerQualifiByType(type))
//过滤空值
.filter(Objects::nonNull)
//排序 以code
.sorted(Comparator.comparing(QualifiVo::getCode))
//去重
.distinct()
.collect(Collectors.toList());
13、查询结果集,匹配
boolean aa = strs.stream().anyMatch(str -> str.equals("a"));
boolean bb = strs.stream().allMatch(str -> str.equals("a"));
boolean cc = strs.stream().noneMatch(str -> str.equals("a"));
14、结果集排序
list.stream().sorted((x, y) -> x.getCode() > y.getCode() ? 1 : -1)
15、对Map排序,可根据Map key或者value进行排序
//以Key正序排列
String a = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).findFirst().get().getValue();
//以Key倒序排列
String b = map.entrySet().stream().sorted(Map.Entry.<Integer, String>comparingByKey().reversed()).findFirst().get().getValue();
//以Value正序排列
String c = map.entrySet().stream().sorted(Map.Entry.comparingByValue()).findFirst().get().getValue();
//以Value倒序排列
String d = map.entrySet().stream().sorted(Map.Entry.<Integer, String>comparingByValue().reversed()).findFirst().get().getValue();
16、List<T> T对象根据外部的 枚举对象就行排序
rs.getData()
.sort(Comparator.comparing(p -> QualifEnum.valueOf(p.getCertType()).getCode()));
17、max 取集合中的时间最大值或者其他最大值
areaList.parallelStream().map(VenderReceiveAreaVO::getModified).max(Comparator.comparing(Date::getTime)).get();
18、Optional<T> 用法
Optional.orElse(null); 如果为空,则返回null
19、Random随机数
Random random = new Random();
random.ints(1,100).limit(10).forEach(System::out::println);
20、计算集合元素的最大值、最小值、总和以及平均值
//获取数字的个数、最小值、最大值、总和以及平均值
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());
21、反转排序,Comparator(reverse Comparator)——我们可以快速地利用它来反转我们的排序
List<Human> humans = Lists.newArrayList(
new Human("Sarah", 10), new Human("Jack", 12));
Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
humans.sort(comparator.reversed());
Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
22、多条件组合排序
List<Human> humans = Lists.newArrayList(
new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12));
humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
23、指定线程数
ForkJoinPool fjp = new ForkJoinPool(3);
System.out.println("My pool: " + fjp);
String result = CompletableFuture.supplyAsync(
() -> Stream.of("a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c").parallel()
.peek(x -> {
System.out.println(Thread.currentThread() + "_" + x);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
})
.collect(Collectors.joining()), fjp).join();
System.out.println(result);
24、简单的分组使用
List.stream().collect(Collectors.groupingBy(RecBillPO::getBillNo))
25、peek() 改变元素的内部状态
List<String> collect = Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("过滤值: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("映射值: " + e))
.collect(Collectors.toList());