JDK8新特性使用记录

一、对象list转map、list

对象如下:

class User{
	String name;
	String id;
}

list集合如下:

List<User> userList = List.newArrayList(
        new User().setId("1").setName("李雷"),
        new User().setId("2").setName("林涛"),
        new User().setId("3").setName("汤姆")
);

过去要是用for循环取值并put到map中去,现在使用jdk8新特性,如下:

Map<String , String> map = userList .stream().collect(Collectors.toMap(User::getId, User::getName));

防止key冲突:

Map<String , String> map = userList .stream().collect(Collectors.toMap(User::getId, User::getName, (f1, f2) -> f1));

防止key冲突(分组):
(假设ID不是唯一键)将相同ID的的 name 放在一个集合中。

Map<String, Set<String>> map2 = userList .stream().collect(Collectors.groupingBy(User::getId, Collectors.mapping(User::getName, Collectors.toSet())));

如果参数为对象:

Map<String , User> map = userList .stream().collect(Collectors.toMap(User::getId, t ->t));

取某一属性转list或set:

Set<String> set = userList.stream().map(User::getId).collect(Collectors.toSet());

二、map的用法

取list中对象的某个属性存入新的list在上一节已经使用过了,这里写一个复杂一点的,比如将list中的User对象转为其他对象后返回一个新List:

List<User2> userList2 = userList.stream.map(
											a -> {
												User2 user2 = 处理方法(a);
												return user2;
												}
											)
										.collect(Collectors.toList());

三、“::”的用法

如上【对象list转map】的示例中所示,双冒号的用法,就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下。
如1.8之前list转map:

for(User user : userList ){
	map.put(user.getId , user.getName());
}

四、并行流

并行流 parallelStream \ IntStream.parallel()
使用方法与stream一样,是一种多线程异步任务。
如 parallelStream() 分段查询结果集:

public Set<String> getAllDto(){
	List<Dto1> allDto = new ArrayList<>();
	List<Runnable> taskList = new ArrayList<Runnable>() {
         {
           for (int i = 1; i < 5; i++) {
               final int a = i;
               add(() -> allDto.addAll(getDto1(a)));
           }
         }
    };
	taskList.parallelStream().forEach(v -> v.run());
}
private List<Dto1> getDto1(int a){
        RequestClass query = new RequestClass() ;
        query.setPage(a);
        List<Dto1>> pageResult = service1.queryDto1(query);
        return pageResult;
    }

可替换为 IntStream.parallel():

private List<Dto1> getDto1(int a){
		//总页数
		int page = 9;
		List<Dto1> allList = IntStream.range(1,page + 1)
                .boxed()
                .parallel()
                .map(page -> {
                    RequestClass query = new RequestClass() ;
					query.setPage(page);
                    return Optional.ofNullable(service1.queryDto1(query))
                        .orElse(Collections.emptyList());
                })
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
			
    }

flatMap()的用法(如根据ID集合批量查询):

//所有ID集合
List<String> allIdList = new ArrayList<>(Arrays.asList("1","2","3"));
//集合切片
List<List<String>> idList = Lists.partition(allIdList , 10);
//设置默认线程池并发数
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4");
/* //或者使用此方法修改默认线程池参数
ForkJoinPool forkJoinPool = new ForkJoinPool(8);
try{
    //查询用户
	List<User> userList = forkJoinPool.submit(() -> idList.parallelStream()
						.map(p -> getUserListByIds(p))
						.flatMap(Collection::stream)
						.collect(Collectors.toList())
					).get();	

}catch (InterruptedException e) {
    e.printStackTrace();
} catch (Exception e){
    e.printStackTrace();
}finally {
    forkJoinPool.shutdown();
}
*/
//查询用户
List<User> userList = idList.parallelStream()
							.map(p -> getUserListByIds(p))
							.flatMap(Collection::stream)
							.collect(Collectors.toList());						

这段代码中,flatMap() 的作用就是将 map返回的集合扁平化,更直观的展示如下代码:

public static void main(String[] args) {
        List<String> strList = new ArrayList<>(Arrays.asList("Hello","World"));
        List<String> streamList = strList.parallelStream().map(word -> word.split(""))
                .flatMap(t -> Arrays.stream(t))
                .collect(toList());
        System.out.println("streamList = " + JSONObject.toJSONString(streamList));
    }

执行结果:

streamList = ["H","e","l","l","o","W","o","r","l","d"]

注意事项:并行流使用的默认线程池是 ForkJoinPool,当服务器核心数大于2时使用线程池,若不大于2,则不使用线程池,直接创建线程执行多线程任务,ArrayList会有线程安全问题,所以在处理复杂业务时要注意线程数量及线程安全问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值