JDK8新特性
一、stream流
1、概念
1.1 基本概念
Stream将要处理的集合或者数组看作一种流,在流中,通过Stream API对流中的元素进行操作,简化了代码。 比如:过滤、筛选、排序、聚合、循环、分页、去重等。1.2 顺序流和并行流
1.stream顺序流: 由主线程按顺序,从上到下从左到右对流执行操作2.parallelStream并行流:异步处理机制,内部以多线程并行执行的方式对流进行操作, 提高了执行效率。适用于对业务或者流程操作没有指定顺序要求。返回结果是无序的。
parallelStream并行流并不是线程安全的,并发时存在数据丢失的情况,在往普通的collection中add数据时会出现抢占资源的线程问题,导致数据随机丢失。
多线程并发问题(可能导致数据丢失或者索引越界异常)
1.3 Stream特性
1.stream不存储数据而是按照特定的规则对数据进行计算一般会输出结果。2.stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
3.stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。
2、流对象创建
2.1 stream 顺序流
1.所有的 Collection 集合都可以通过 stream() 方法来获取流对象; Map集合 没有继承 Collection 接口,所以无法通过 stream()方法获取流对象2.使用 Stream 接口的 of() 静态方法获取流对象。
基本类型数组会把整个数组看作一个元素来操作 Stream<int[]> ints1 = Stream.of(ints);
/**
* Stream 顺序流对象获取
* @param args
*/
public static void main(String[] args) {
//方式1:根据Collection获取流对象
//List获取流
List<Integer> integers = Arrays.asList(1, 23, 45, 66,null);
Stream<Integer> listStream = integers.stream();
//2.Set获取流
Set<Integer> set = new HashSet<>();
Stream<Integer> setStream = set.stream();
//3.Map获取流
//Map 没有继承 Collection 接口,所有无法通过该 stream()方法获取流对象
Map<Object, Object> hashMap = new HashMap<>();
Stream<Map.Entry<Object, Object>> stream = hashMap.entrySet().stream();
Stream<Object> objectStream = hashMap.keySet().stream();
Stream<Object> stream1 = hashMap.values().stream();
//方式2:Stream中的静态方法of获取流对象
//1.字符串获取流对象
Stream<Integer> integerStream = Stream.of(1, 2, 3, 555);
//2.数组类型
//基本类型会把整个数据看作一个元素来操作
int[] ints = {1,2,344,5};
Stream<int[]> ints1 = Stream.of(ints);
ints1.forEach(o -> {
for (int i : o) {
System.out.println(i);//1 2 344 5
}
});
//使用java.util.Arrays.stream(T[] array)方法用数组创建流
int[] array = {1,2,5,6,7};
IntStream stream3 = Arrays.stream(array);
//包装类数组
Integer[] integeres = {1,2,344,5};
Stream<Integer> stream2 = Stream.of(integeres);
stream2.forEach(o -> System.out.println(o));//1 2 344 5
}
}
2.2 parallelStream 并行流
/**
* parallelStream并行流对象获取
* @param args
*/
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 23, 45, 66,null);
Stream<Integer> integerStream = integers.parallelStream();
//把顺序流转为并发流
int[] ints = {1,23,45,67};
IntStream parallel = Arrays.stream(ints).parallel();
}
2.3 顺序流转换成并行流
/**
* 顺序流转为并发流
* @param args
*/
public static void main(String[] args) {
//顺序流转为并发流
List<Integer> integers = Arrays.asList(1, 23, 45, 66,null);
Stream<Integer> parallel = integers.stream().parallel();
}
3、使用
3.1 匹配 - allMatch / anyMatch
3.1.1 allMatch
对流中所有元素按指定条件匹配,全部满足返回true,否则返回false
注:
若比较的元素或者属性有null值会报空指针异常,需要做空值过滤
包装类集合: filter(Objects::nonNull)
对象集合: filter(o -> ObjectUtil.isNotNull(o.getId()))
/**
* 包装类集合
* @param args
*/
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 23, 45, 66, null);
boolean b = integers
.stream()
.filter(Objects::nonNull)
.allMatch(o -> o > 0);
boolean c = integers
.stream()
.filter(Objects::nonNull)
.allMatch(o -> o > 10);
System.out.println(b);//true
System.out.println(c);//false
}
/**
* 对象集合
* @param args
*/
public static void main(String[] args) {
List<CityRequest> cityRequestList = new ArrayList<>();
cityRequestList.add(CityRequest.builder().id(null).build());
cityRequestList.add(CityRequest.builder().id(2).build());
cityRequestList.add(CityRequest.builder().id(100).build());
//判断id是否都大于等于2
boolean result = cityRequestList.stream()
.filter(o -> ObjectUtil.isNotNull(o.getId()))
.allMatch(o -> o.getId().compareTo(2) >= 0);
System.out.println(result);//true
}
3.1.2 anyMatch
对流中所有元素按指定条件匹配,至少有一个满足返回true,都不满足返回false
注:
若比较的元素或者属性有null值会报空指针异常,需要做空值过滤
包装类集合: filter(Objects::nonNull)
对象集合: filter(o -> ObjectUtil.isNotNull(o.getId()))
/**
* 对象集合
* @param args
*/
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).build());
list.add(CityRequest.builder().id(1).build());
list.add(CityRequest.builder().id(234).build());
List<CityRequest> cityRequests = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getId()))
.collect(Collectors.toList());
boolean b = cityRequests.stream()
.anyMatch(o -> o.getId().equals(4));
boolean c = cityRequests.stream()
.anyMatch(o -> o.getId().equals(234));
System.out.println(b);//false
System.out.println(c);//true
}
3.2 循环/查找 - forEach / findFirst / findAny
/**
* 对象集合
* @param args
*/
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
//获取第一个元素
CityRequest cityRequest = null;
Optional<CityRequest> first = list.stream()
.filter(o -> o.getParentId().equals(1))
.findFirst();
System.out.println(first.orElse(null));
//CityRequest(id=null, parentId=1, cityName=null, sort=null, isChoice=null)
//返回的是过滤后的符合条件的第一个
Optional<CityRequest> request = list.stream()
.filter(o -> o.getParentId().equals(1))
.findAny();
System.out.println(request.orElse(null));
//CityRequest(id=null, parentId=1, cityName=null, sort=null, isChoice=null)
//随机返回,不一定会返回哪一个
Optional<CityRequest> any = list.parallelStream().findAny();
System.out.println(any.orElse(null));
//CityRequest(id=234, parentId=3, cityName=null, sort=null, isChoice=null)
//给集合的每一个元素的isChoice赋值
list.stream().forEach(o ->{
o.setIsChoice("1");
});
}
3.3 过滤 - filter
3.3.1 筛选城市名称为西安的数据集合
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
System.out.println(list.stream()
.filter(o -> "西安".equals(o.getCityName()))
.collect(Collectors.toList())
);
//[CityRequest(id=234, parentId=1, cityName=西安, sort=null, isChoice=null)]
}
3.3.2 筛选parentId大于1的数据集合
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
List<CityRequest> collect = list.stream()
.filter(o -> o.getParentId() > 1)
.collect(Collectors.toList());
System.out.println(collect);
//[CityRequest(id=1, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=234, parentId=3, cityName=null, sort=null, isChoice=null)]
}
3.4 聚合 - max / min / count
3.4.1 max - 最大值
查询parentId最大的元素
若有重复的,顺序(从上到下)取第一个
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
Optional<CityRequest> cityRequest = list.stream()
.max(Comparator.comparing(CityRequest::getParentId));
System.out.println(cityRequest.orElse(null));
//CityRequest(id=9, parentId=3, cityName=null, sort=null, isChoice=null)
}
3.4.2 min - 最小值
查询parentId最小的元素
若有重复的,顺序(从上到下)取第一个
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
Optional<CityRequest> cityRequest = list.stream()
.min(Comparator.comparing(CityRequest::getParentId));
System.out.println(cityRequest.orElse(null));
//CityRequest(id=null, parentId=1, cityName=null, sort=null, isChoice=null)
}
3.4.3 count - 总记录数
查询parentId等于3的有多少个
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(3).build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
long count = list.stream()
.filter(o -> o.getParentId().equals(3))
.count();
System.out.println(count);//2
}
3.5 映射 - map / flatMap
3.5.1 map
接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。即对参数的每一个元素进行处理后生成新的元素
3.5.1.1 获取所有parentId为3的所有的城市名称集合
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
List<String> cityNames = list.stream()
.filter(o -> o.getParentId().equals(3))
.map(CityRequest::getCityName)
.collect(Collectors.toList());
System.out.println(cityNames);//[成都, 北京]
}
3.5.1.2 给所有parentId为3的元素parentId + 1
会改变源集合的值
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
//会改变源集合的值
List<CityRequest> collect = list.stream()
.filter(o -> o.getParentId().equals(3))
.map(o -> {
o.setParentId(new BigDecimal(o.getParentId()).add(new BigDecimal("1")).intValue());
return o;
}).collect(Collectors.toList());
System.out.println(list);
//[CityRequest(id=null, parentId=1, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=4, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=1, cityName=西安, sort=null, isChoice=null)]
System.out.println(collect);
//[CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=4, cityName=北京, sort=null, isChoice=null)]
}
不会改变源集合的值
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(1).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
//不会改变源集合的值
List<CityRequest> collect = list.stream()
.filter(o -> o.getParentId().equals(3))
.map(o -> {
CityRequest request = CityRequest.builder().build();
BeanUtils.copyProperties(o,request);
request.setParentId(new BigDecimal(o.getParentId())
.add(new BigDecimal("1")).intValue());
return request;
}).collect(Collectors.toList());
System.out.println(list);
//[CityRequest(id=null, parentId=1, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=9, parentId=3, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=3, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=1, cityName=西安, sort=null, isChoice=null)]
System.out.println(collect);
//[CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=4, cityName=北京, sort=null, isChoice=null)]
}
3.5.1.2 调用本类中的方法
调用本类中的方法,方法参数为集合中遍历的每个元素,自定义流返回的数据:
list.stream().map(CityController::getCityRequestList).collect(Collectors.toList());
public static CityRequest getCityRequestList(CityRequest request){
if(ObjectUtil.isNotNull(request.getId()) && request.getId().equals(1)){
request.setIsChoice("666");
}
return request;
}
public static List<CityRequest> getObj(){
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
list.add(CityRequest.builder().id(900).parentId(8).cityName("西安").build());
return list.stream()
.map(CityController::getCityRequestList)
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<CityRequest> obj = getObj();
System.out.println(obj);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=666),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=900, parentId=8, cityName=西安, sort=null, isChoice=null)]
}
3.5.1.2 map转list
private List<ServiceOrderDetailResponse.ServiceGoods> handleProductList(JSONArray jsonArray) {
return jsonArray.stream()
.map(JSONObject.class::cast)
.map(o -> {
ServiceOrderDetailResponse.ServiceGoods serviceGood = new ServiceOrderDetailResponse.ServiceGoods();
serviceGood.setProductId(o.getLong("spuId"));
serviceGood.setCatOne(o.getLong("cat1"));
serviceGood.setDesc(o.getString("description"));
serviceGood.setPackageId(o.getLong("spuId"));
serviceGood.setProductPrice(o.getBigDecimal("productPrice"));
return serviceGood;
})
.collect(Collectors.toList());
}
3.5.2 flatMap
接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
将两个字符数组合并成一个新的字符数组
public static void main(String[] args) {
List<String> strings = Arrays.asList("1,2,3", "4,5,6");
System.out.println(strings);//[1,2,3, 4,5,6]
List<String> collect = strings.stream().flatMap(s -> {
// 将每个元素转换成一个stream
String[] split = s.split(",");
return Arrays.stream(split);
}).collect(Collectors.toList());
System.out.println(collect);//[1, 2, 3, 4, 5, 6]
}
3.6 归约 - reduce
通过计算将所有流转为一个结果值,对集合或者数组进行累加、乘积、最值操作
3.6.1 求所有数据的parentId总和
累加的数据有null值,会报空指针异常,
需要过滤null值:filter(o -> ObjectUtil.isNotNull(o.getParentId()))
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(null).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
//方式一
Optional<Integer> reduce = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getParentId()))
.map(CityRequest::getParentId)
.reduce(Integer::sum);
System.out.println(reduce.orElse(null));//9
//方式二
Integer integer = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getParentId()))
.reduce(0, (sum, p) -> sum += p.getParentId(), Integer::sum);
System.out.println(integer);//9
}
3.6.2 求所有数据的parentId的乘积
要相乘的数据有null值,会报空指针异常,
需要过滤null值:filter(o -> ObjectUtil.isNotNull(o.getParentId()))
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(null).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
Optional<Integer> reduce = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getParentId()))
.map(CityRequest::getParentId)
.reduce((x, y) -> x * y);
System.out.println(reduce.orElse(null));//18
}
3.6.3 求所有数据的parentId的最大值
要比较的数据有null值,会报空指针异常,
需要过滤null值:filter(o -> ObjectUtil.isNotNull(o.getParentId()))
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(null).build());
list.add(CityRequest.builder().id(1).parentId(2).build());
list.add(CityRequest.builder().id(9).parentId(3).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(3).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(1).cityName("西安").build());
//方式一
Optional<Integer> reduce = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getParentId()))
.map(CityRequest::getParentId)
.reduce((x, y) -> x > y ? x : y);
//方式二
Integer integer = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getParentId()))
.map(CityRequest::getParentId)
.reduce(0, Integer::max);
System.out.println(reduce.orElse(null));//3
System.out.println(integer);//3
}
3.6.4 求所有分账金额的和
累加的数据有null值,会报空指针异常,
需要过滤null值:filter(Objects::nonNull)
没有符合条件最后返回 0
public static void main(String[] args) {
List<ChPayLedgerBillLogRequest> requests = Arrays.asList(
ChPayLedgerBillLogRequest.builder().dimensionAmount(null).build(),
ChPayLedgerBillLogRequest.builder().dimensionAmount(new BigDecimal("100.98")).build(),
ChPayLedgerBillLogRequest.builder().dimensionAmount(new BigDecimal("98.99")).build());
BigDecimal reduce = requests.stream()
.map(ChPayLedgerBillLogRequest::getDimensionAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(reduce);//199.97
}
3.7 收集 - collect
经过流处理过的数据的结果集装到哪个容器中。
3.7.1 toList / toSet / toMap
收集为map时,允许null key,不允许null value 。
key有重复的会报错:java.lang.IllegalStateException: Duplicate key
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//收集属性
//list
List<Integer> collect = list.stream()
.map(CityRequest::getId)
.collect(Collectors.toList());
System.out.println(collect);//[null, 1, 9, 234, 234]
//set
Set<Integer> set = list.stream()
.map(CityRequest::getId)
.collect(Collectors.toSet());
System.out.println(set);//[null, 1, 9, 234]
//map key允许为null,value不允许为null ,需要做null值处理
Map<Integer, String> requestMap = list.stream()
.collect(Collectors.toMap(CityRequest::getId,
o -> ObjectUtil.isNull(o.getCityName()) ? "" : o.getCityName(),(o1, o2) -> o1));
System.out.println(requestMap);
//{null=, 1=海南, 9=成都, 234=北京}
//收集对象集合
//list
List<CityRequest> requestList = list.stream()
.collect(Collectors.toList());
System.out.println(requestList);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
//set
Set<CityRequest> requestSet = list.stream()
.collect(Collectors.toSet());
System.out.println(requestSet);
//[CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null)]
//map 如果key有相同的取第一个
Map<Integer, CityRequest> map = list.stream()
.collect(Collectors.toMap(CityRequest::getId, Function.identity(), (o1, o2) -> o1));
System.out.println(map);
//{null=CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// 1=CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// 9=CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// 234=CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null)}
}
3.7.2 统计 count / averaging
统计的值有null值,会报空指针异常:
null值处理:filter(o -> ObjectUtil.isNotNull(o.getId()))
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//总数 如果要统计的值有null值,会报空指针异常
long count = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getId()) && o.getId() > 1)
.count();
System.out.println(count);//3
//平均id 如果要统计的值有null值,会报空指针异常
Double collect = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getId()))
.collect(Collectors.averagingInt(CityRequest::getId));
System.out.println(collect);//119.5
}
3.7.3 分组 partitioningBy groupingBy
partitioningBy :按照条件分组。分组的属性有null会报空指针异常
groupingBy:按照属性分组。分组后的key有null值报空指针异常:element cannot be mapped to a null key
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//根据id大于9分组 分组的属性有null会报空指针异常 此处处理如果为空算在小于9里面
Map<Boolean, List<CityRequest>> collect = list.stream()
.map(o -> {
o.setId(ObjectUtil.isNull(o.getId()) ? 0 : o.getId());
return o;
}).collect(Collectors.partitioningBy(o -> o.getId() > 9));
System.out.println(collect);
//{false=[CityRequest(id=0, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null)],
// true=[CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]}
//根据城市名称分组 key为空报空指针异常:element cannot be mapped to a null key
Map<String, List<CityRequest>> listMap = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getCityName()))
.collect(Collectors.groupingBy(CityRequest::getCityName));
System.out.println(listMap);
//{成都=[CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null)],
// 西安=[CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)],
// 海南=[CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null)],
// 北京=[CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null)]}
}
3.7.4 连接 joining
将流中的元素按指定规则链接
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
String collect = list.stream()
.map(CityRequest::getCityName)
.collect(Collectors.joining("-"));
System.out.println(collect);//null-海南-成都-北京-西安
}
3.8 排序 - sorted
sorted():升序
sorted(Comparator.comparing(CityRequest::getParentId).reversed(): 降序
排序的属性有null值报错,需要null值处理
sorted(Comparator.comparing(CityRequest::getId,Comparator.nullsFirst(Ineger::compare)))
nullsLast():null最大
nullsFirst():null最小
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//按parentId降序排序 排序的属性有null会报错
List<CityRequest> requestList = list.stream()
.sorted(Comparator.comparing(CityRequest::getParentId).reversed())
.collect(Collectors.toList());
//按parentId升序 排序的属性有null会报错
List<CityRequest> requests = list.stream()
.sorted(Comparator.comparing(CityRequest::getParentId))
.collect(Collectors.toList());
//parentId升序排序
List<CityRequest> collect = list.stream()
.sorted((o1, o2) -> o1.getParentId().compareTo(o2.getParentId()))
.collect(Collectors.toList());
System.out.println(collect);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
//parentId降序排序
List<CityRequest> cityRequestList = list.stream()
.sorted((o1, o2) -> o2.getParentId().compareTo(o1.getParentId()))
.collect(Collectors.toList());
System.out.println(cityRequestList);
//[CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null)]
//id降序排序 null值最大
List<CityRequest> collect = list.stream()
.sorted(Comparator.comparing(CityRequest::getId,Comparator.nullsLast(Integer::compare)).reversed())
.collect(Collectors.toList());
System.out.println(collect);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null)]
//id升序排序 null最小
List<CityRequest> requests = list.stream()
.sorted(Comparator.comparing(CityRequest::getId, Comparator.nullsFirst(Integer::compare)))
.collect(Collectors.toList());
System.out.println(requests);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
}
3.9 分页 - skip / limit
skip:开始的索引 = (当前的页 - 1) * 每页记录数
limit:每页记录数
/**
* 分页
* @param pageNow 当前页
* @param pageSize 每页记录数
* @return
*/
public static List<CityRequest> limit(Integer pageNow,Integer pageSize){
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
list.add(CityRequest.builder().id(900).parentId(8).cityName("西安").build());
pageSize = ObjectUtil.isNull(pageSize) ? 10 : pageSize;
return list.stream()
.sorted(Comparator.comparing(CityRequest::getId,Comparator.nullsLast(Integer::compareTo))
.thenComparing(Comparator.comparing(CityRequest::getParentId).reversed()))
.skip(ObjectUtil.isNull(pageNow) ? 0 : (long) (pageNow - 1) * pageSize)
.limit(pageSize).collect(Collectors.toList());
}
/**
* 分页
* @param args
*/
public static void main(String[] args) {
List<CityRequest> limit = limit(null, null);
//[CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=900, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null)]
System.out.println(limit);
List<CityRequest> requests = limit(1, 3);
System.out.println(requests);
//[CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
List<CityRequest> cityRequests = limit(2, 3);
System.out.println(cityRequests);
//[CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=900, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null)]
}
4.0 去重 - distinct
紧跟着的集合的所有元素(对象属性)去重
如需根据过滤后的集合去重需要在map/filter后 collect收集元素前去重
List<BusinessRefundNotifyResponse> businessRefundNotifyResponses = Arrays.asList(
BusinessRefundNotifyResponse.builder().heliPayOrderNo("123").refundAmount(new BigDecimal("100")).build(),
BusinessRefundNotifyResponse.builder().heliPayOrderNo("123").refundAmount(new BigDecimal("100")).build()
);
//对businessRefundNotifyResponses集合去重
List<BusinessRefundNotifyResponse> collect = businessRefundNotifyResponses.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(collect.size());//1
//对collect 集合去重
List<String> strings = collect.stream()
.distinct()
.map(BusinessRefundNotifyResponse::getHeliPayOrderNo)
.collect(Collectors.toList());
System.out.println(strings);//[123]
List<BusinessRefundNotifyResponse> list = Arrays.asList(
BusinessRefundNotifyResponse.builder().heliPayOrderNo("123").refundAmount(new BigDecimal("100")).build(),
BusinessRefundNotifyResponse.builder().heliPayOrderNo("124").refundAmount(new BigDecimal("100")).build()
);
//对list集合去重
List<BusinessRefundNotifyResponse> responses = list.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(responses.size());//2
//对list集合里面的heliPayOrderNo属性去重
List<String> stringList = list.stream()
.map(BusinessRefundNotifyResponse::getHeliPayOrderNo)
.distinct()
.collect(Collectors.toList());
System.out.println(stringList);//[123, 124]
二、jdk8常用的集合方法
1.1 条件删除 - removeIf
按条件删除集合中的元素
注:
如果要删除的元素或者删除的条件有null值,则会报空指针异常,需要对原集合过滤null值
包装类集合: filter(Objects::nonNull)
对象集合: filter(o -> ObjectUtil.isNotNull(o.getId()))
/**
* 包装类集合
* @param args
*/
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3, 4,null));
List<Integer> filterIntegers = integers.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());//过滤空值
filterIntegers.removeIf(inr -> 1 == inr);
System.out.println(integers.toString());//[1, 2, 3, 4, null]
System.out.println(filterIntegers.toString());//[2, 3, 4]
}
/**
* 对象集合
* @param args
*/
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).build());
list.add(CityRequest.builder().id(1).build());
list.add(CityRequest.builder().id(234).build());
List<CityRequest> cityRequests = list.stream()
.filter(o -> ObjectUtil.isNotNull(o.getId()))
.collect(Collectors.toList());
boolean b = cityRequests.removeIf(o -> o.getId().equals(1));
System.out.println(cityRequests);//[CityRequest(id=234, parentId=null, cityName=null, sort=null, isChoice=null)]
System.out.println(b);//true
}
1.2 排序 - sort
无返回值。排序字段有null值,报空指针异常:
处理:
nullsFirst : null最小
nullsLast : null最大
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//id升序 nullsFirst : null最小 ,属性有null:空指针异常
list.sort(Comparator.comparing(CityRequest::getId,Comparator.nullsFirst(Integer::compare)));
System.out.println(list);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
//id倒序 nullsLast:null最大 属性有null:空指针异常
list.sort(Comparator.comparing(CityRequest::getId,Comparator.nullsLast(Integer::compareTo)).reversed());
System.out.println(list);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null)]
//id倒序在按parentId升序 nullsLast:null最大 属性有null:空指针异常
list.sort(Comparator.comparing(CityRequest::getId,Comparator.nullsLast(Integer::compareTo))
.reversed().thenComparing(CityRequest::getParentId,Comparator.nullsFirst(Integer::compareTo)));
System.out.println(list);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=null)]
}
1.3 遍历 - forEach
遍历集合,无返回值。
public static void main(String[] args) {
List<CityRequest> list = new ArrayList<>();
list.add(CityRequest.builder().id(null).parentId(2).build());
list.add(CityRequest.builder().id(1).parentId(2).cityName("海南").build());
list.add(CityRequest.builder().id(9).parentId(4).cityName("成都").build());
list.add(CityRequest.builder().id(234).parentId(6).cityName("北京").build());
list.add(CityRequest.builder().id(234).parentId(8).cityName("西安").build());
//给id为1的赋值isChoice赋值
list.forEach(o ->{
if(ObjectUtil.isNotNull(o.getId()) && o.getId().equals(1)){
o.setIsChoice("100");
}
});
System.out.println(list);
//[CityRequest(id=null, parentId=2, cityName=null, sort=null, isChoice=null),
// CityRequest(id=1, parentId=2, cityName=海南, sort=null, isChoice=100),
// CityRequest(id=9, parentId=4, cityName=成都, sort=null, isChoice=null),
// CityRequest(id=234, parentId=6, cityName=北京, sort=null, isChoice=null),
// CityRequest(id=234, parentId=8, cityName=西安, sort=null, isChoice=null)]
}