- Published on
Java8-Stream流式编程
开发中常用的语法汇总
JDK 提供三个静态方法来构造一个 Optional:
1.Optional.of(T value),该方法通过一个非 null 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为 null,否则便会抛出 NullPointerException。
2.Optional.ofNullable(T value),该方法和 of 方法的区别在于,传入的参数可以为 null —— 但是前面 javadoc 不是说 Optional 只能包含非 null 值吗?我们可以看看 ofNullable 方法的源码:
userMapList.forEach((k, v) -> userList.add((Func.toBean(v,Object.class)));
List<TsUserExtendDTO> userList = userMapList.entrySet()
.stream()
.map(e -> BeanUtil.toBean((Map)e.getValue(),TsUserExtendDTO.class))
.collect(Collectors.toList());
// 遍历map
map.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));
// map转list
map.entrySet().stream().map(e -> new Person(e.getKey(),e.getValue())).collect(Collectors.toList());
// list转map
Map<Integer, String> result1 = list.stream().collect(Collectors.toMap(Hosting::getId, Hosting::getName));
// 如果有重复key 参考 https://blog.csdn.net/wangmuming/article/details/78518301
Map<String, BranchConnectUserDTO> brancheMaps = branchData.stream().collect(Collectors.toMap(BranchConnectUserDTO::getId, v -> v));
// 交集
List<String> intersection = list1.stream().filter(item -> list2.contains(item)).collect(toList());
System.out.println("---得到交集 intersection---");
intersection.parallelStream().forEach(System.out :: println);
// 差集 (list1 - list2)
List<String> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(toList());
System.out.println("---得到差集 reduce1 (list1 - list2)---");
reduce1.parallelStream().forEach(System.out :: println);
// 差集 (list2 - list1)
List<String> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(toList());
System.out.println("---得到差集 reduce2 (list2 - list1)---");
reduce2.parallelStream().forEach(System.out :: println);
// 并集
List<String> listAll = list1.parallelStream().collect(toList());
List<String> listAll2 = list2.parallelStream().collect(toList());
listAll.addAll(listAll2);
System.out.println("---得到并集 listAll---");
listAll.parallelStream().forEach(System.out :: println);
// 去重并集
List<String> listAllDistinct = listAll.stream().distinct().collect(toList());
System.out.println("---得到去重并集 listAllDistinct---");
listAllDistinct.parallelStream().forEach(System.out :: println);
System.out.println("---原来的List1---");
list1.parallelStream().forEach(System.out :: println);
System.out.println("---原来的List2---");
list2.parallelStream().forEach(System.out :: println);
// 一般有filter 操作时,不用并行流parallelStream ,如果用的话可能会导致线程安全问题
java8 list统计(求和、最大、最小、平均)
List<Integer> numbers1 = Arrays.asList(3, 5, 1, 2, 4);
numbers1.sort(Comparator.naturalOrder());
System.out.println(numbers1); // [1, 2, 3, 4, 5]
List<Long> numbers2 = Arrays.asList(111L, 222L, 333L, 444L, 555L);
numbers2.sort(Comparator.naturalOrder());
System.out.println(numbers2); // [111, 222, 333, 444, 555]
List<String> numbers3 = Arrays.asList("b", "a", "c", "d", "e");
numbers3.sort(Comparator.naturalOrder());
System.out.println(numbers3); // [a, b, c, d, e]
Java 8 Stream Collectors groupingBy 示例
package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Java8Examples3 {
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
Map<String, Long> counting = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.counting()));
System.out.println(counting);
Map<String, Integer> sum = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
System.out.println(sum);
}
}
使用 Lambda 表达式的正确姿势链接
1. 使用java8的lambda将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<Long, List<ActivityUserMissionDO>> map = activityUserMissionDos.stream().
collect(Collectors.groupingBy(ActivityUserMissionDO::getParentModuleId));
指定具体收集的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));
}
String keys = Arrays.stream(fields).collect(Collectors.joining(","));
java8用lambda表达式获取List中所有元素的某个值并转成List
Set<Integer> categoryTypes = productInfos.stream().map(e -> e.getCategoryType()).collect(Collectors.toSet());
List<ShoppingCarDTO> shoppingCarDTOList = orderDTO.getOrderDetailList().
stream().map( e ->
new ShoppingCarDTO(e.getProductId(),e.getProductQuantity())).collect(Collectors.toList());
JAVA8字符串转数组、数组转List
public class function {
public static void main(String[] args){
String str = "1,2,3";
int[] a = Arrays.stream(str.split(",")).mapToInt(s -> Integer.parseInt(s)).toArray();
int[] src = {1,2,3,4,5,6,7,8,9,10};
List<Integer> list = Arrays.stream(src).boxed().collect(Collectors.toList());
for (int i=0; i<a.length; i++){
System.out.println(a[i]);
}
for (int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
//java8特性//将以逗号分割的字符串转换成List<Long>类型
String ids= "1,2,3,4,5,6";
List<Long> idList = Arrays.asList(ids.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
System.out.println( idList.toString());
//将List<Long>类型转换成以逗号分割的字符串
String list = StringUtils.join(idList, ",");
String str= StringUtils.strip(list.toString(), "[]");
System.out.println(str);
}
}
Java8中Map的遍历方式总结
public class LambdaMap {
private Map<String, Object> map = new HashMap<>();
@Before
public void initData() {
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key4", 4);
map.put("key5", 5);
map.put("key5", 'h');
}
/**
* 遍历Map的方式一
* 通过Map.keySet遍历key和value
*/
@Test
public void testErgodicWayOne() {
System.out.println("---------------------Before JAVA8 ------------------------------");
for (String key : map.keySet()) {
System.out.println("map.get(" + key + ") = " + map.get(key));
}
System.out.println("---------------------JAVA8 ------------------------------");
map.keySet().forEach(key -> System.out.println("map.get(" + key + ") = " + map.get(key)));
}
/**
* 遍历Map第二种
* 通过Map.entrySet使用Iterator遍历key和value
*/
@Test
public void testErgodicWayTwo() {
System.out.println("---------------------Before JAVA8 ------------------------------");
Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue());
}
System.out.println("---------------------JAVA8 ------------------------------");
map.entrySet().iterator().forEachRemaining(item -> System.out.println("key:value=" + item.getKey() + ":" + item.getValue()));
}
/**
* 遍历Map第三种
* 通过Map.entrySet遍历key和value,在大容量时推荐使用
*/
@Test
public void testErgodicWayThree() {
System.out.println("---------------------Before JAVA8 ------------------------------");
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue());
}
System.out.println("---------------------JAVA8 ------------------------------");
map.entrySet().forEach(entry -> System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue()));
}
/**
* 遍历Map第四种
* 通过Map.values()遍历所有的value,但不能遍历key
*/
@Test
public void testErgodicWayFour() {
System.out.println("---------------------Before JAVA8 ------------------------------");
for (Object value : map.values()) {
System.out.println("map.value = " + value);
}
System.out.println("---------------------JAVA8 ------------------------------");
map.values().forEach(System.out::println); // 等价于map.values().forEach(value -> System.out.println(value));
}
/**
* 遍历Map第五种
* 通过k,v遍历,Java8独有的
*/
@Test
public void testErgodicWayFive() {
System.out.println("---------------------Only JAVA8 ------------------------------");
map.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));
}
}
// 双重遍历
attributes.forEach(conf -> authorities.forEach(auth -> {
if (conf.getAttribute().equals(auth.getAuthority())) {
result.getAndIncrement();
}
}));
介绍java中Pair
在这篇文章中,我们讨论了一个非常有用的编程概念,配对(Pair)。配对提供了一种方便方式来处理简单的键值关联,当我们想从方法返回两个值时特别有用。
在核心Java库中可以使用配对(Pair)的实现。除此之外,某些第三方库,比如Apache Commons和Vavr,已经在各自的api中公开了这个功能。
核心java配对实现 Pair类 Pair类在javafx.util 包中,类构造函数有两个参数,键及对应值:
Pair<Integer, String> pair = new Pair<>(1, "One");
Integer key = pair.getKey();
String value = pair.getValue();
示例描述使用Pair类实现简单Integer到String的映射。示例中getKey方法返回key对象,getValue方法返回对应值对象。
AbstractMap.SimpleEntry 和 AbstractMap.SimpleImmutableEntry SimpleEntry定义在抽象类AbstractMap里面,其构造方法与Pair类似:
AbstractMap.SimpleEntry<Integer, String> entry
= new AbstractMap.SimpleEntry<>(1, "one");
Integer key = entry.getKey();
String value = entry.getValue();
其键和值可以通过标准的getter和setter方法获得。
另外AbstractMap 类还包含一个嵌套类,表示不可变配对:SimpleImmutableEntry 类。
AbstractMap.SimpleImmutableEntry<Integer, String> entry
= new AbstractMap.SimpleImmutableEntry<>(1, "one");
应用方式与可变的配对一样,除了配置的值不能修改,尝试修改会抛出UnsupportedOperationException异常。