java8 flatmaptolong_Java8 Stream使用flatMap合并List

之前也写过很多篇关于Java8使用的文章了,但是回顾一下,好像还没介绍过Java8 Stream的flatMap操作,昨天刚好在工作中遇到一个场景,发现flatMap简直太方便了,这里总结一下flatMap的常规使用。附带讲一下,使用Java8实现集合的并、交、差操作,其实之前也讲过一种使用Guava的实现方式,具体请参考Guava集合工具

flatMap

首先看一下一种场景,存在一个Map,ListContainer中存在一个List成员变量。有这样一个需求,讲Map中values中所有的List组合成一个List。我们也许会这样操作:

List resultAClassList = Lists.newArrayList();

for (ListContainer tmp : map.values()){

resultAClassList.addAll(tmp.getLst());

}

这还是只存在一层List的情况,如果存在多层,for还需要嵌套,使用起来很不方便。后来查到,Java8 Stream的flatMap操作可以很好地适用这种场景,首先看一下flatMap方法定义:

Stream flatMap(Function super T, ? extends Stream extends R>> mapper);

参数是一个Function函数式接口,提供T到Stram的转换。其实参考方法实现,flatMap就是将Function转化后的Stram合并成一个Stream。下面看一下使用示例,完成上述相同的功能:

@Test

public void mergeMapValuesTest(){

Map map = Maps.newHashMap();

List aClassList1 = Lists.newArrayList();

AClass aClass = new AClass(1, "zhuoli1", "haha1");

aClassList1.add(aClass);

aClassList1.add(new AClass(2, "zhuoli2", "haha2"));

aClassList1.add(new AClass(3, "zhuoli3", "haha3"));

List aClassList2 = Lists.newArrayList();

aClassList2.add(aClass);

aClassList2.add(new AClass(5, "zhuoli5", "haha5"));

aClassList2.add(new AClass(6, "zhuoli6", "haha6"));

/*交集*/

/*[AClass(id=1, name=zhuoli1, description=haha1)]*/

List intersectResult = aClassList1.stream().filter(aClassList2::contains).collect(Collectors.toList());

System.out.println(intersectResult);

/*并集*/

List unionResult = Stream.of(aClassList1, aClassList2).flatMap(Collection::stream).distinct().collect(Collectors.toList());

assertEquals(unionResult.size(), 5);

System.out.println(unionResult);

/*差集*/

/*[AClass(id=2, name=zhuoli2, description=haha2), AClass(id=3, name=zhuoli3, description=haha3)]*/

List differenceResult = aClassList1.stream().filter(x -> !aClassList2.contains(x)).collect(Collectors.toList());

System.out.println(differenceResult);

map.put(1, new ListContainer(aClassList1));

map.put(2, new ListContainer(aClassList2));

/*合并多个list*/

List aClassListResult = map.values().stream().flatMap(listContainer -> listContainer.getLst().stream()).collect(Collectors.toList());

/*注意跟并集的区别*/

assertEquals(aClassListResult.size(), 6);

System.out.println(aClassListResult);

}

分享一个flatMap的复杂操作,实现List和List根据Id进行连接,将连接结果输出为一个List:

@Data

@AllArgsConstructor

public class Data1 {

private int id;

private String name;

private int amount;

}

@Data

@AllArgsConstructor

public class Data2 {

private int id;

private String name;

private String type;

}

@Data

@AllArgsConstructor

public class OutputData {

private int id;

private String name;

private String type;

private int amount;

}

@Test

public void intersectByKeyTest(){

List listOfData2 = new ArrayList();

listOfData2.add(new Data2(10501, "JOE" , "Type1"));

listOfData2.add(new Data2(10603, "SAL" , "Type5"));

listOfData2.add(new Data2(40514, "PETER", "Type4"));

listOfData2.add(new Data2(59562, "JIM" , "Type2"));

listOfData2.add(new Data2(29415, "BOB" , "Type1"));

listOfData2.add(new Data2(61812, "JOE" , "Type9"));

listOfData2.add(new Data2(98432, "JOE" , "Type7"));

listOfData2.add(new Data2(62556, "JEFF" , "Type1"));

listOfData2.add(new Data2(10599, "TOM" , "Type4"));

List listOfData1 = new ArrayList();

listOfData1.add(new Data1(10501, "JOE" ,3000000));

listOfData1.add(new Data1(10603, "SAL" ,6225000));

listOfData1.add(new Data1(40514, "PETER" ,2005000));

listOfData1.add(new Data1(59562, "JIM" ,3000000));

listOfData1.add(new Data1(29415, "BOB" ,3000000));

List result = listOfData1.stream()

.flatMap(x -> listOfData2.stream()

.filter(y -> x.getId() == y.getId())

.map(y -> new OutputData(y.getId(), x.getName(), y.getType(), x.getAmount())))

.collect(Collectors.toList());

System.out.println(result);

/*difference by key*/

List data1IntersectResult = listOfData1.stream().filter(data1 -> listOfData2.stream().map(Data2::getId).collect(Collectors.toList()).contains(data1.getId())).collect(Collectors.toList());

System.out.println(data1IntersectResult);

}

faltMapToInt

首先看一下flatMapToInt方法定义:

IntStream flatMapToInt(Function super T, ? extends IntStream> mapper);

跟flatMap不同的是,参数Function函数式接口提供由T到IntStream的转化,方法返回值是IntStream。

@Test

public void flatMapToIntTest() {

List> listOfLists = Arrays.asList(

Arrays.asList("1", "2"),

Arrays.asList("5", "6"),

Arrays.asList("3", "4")

);

IntStream intStream =

listOfLists.stream()

.flatMapToInt(childList ->

childList.stream()

.mapToInt(Integer::new));

int sum = intStream.peek(System.out::println).sum();

System.out.println("sum: " + sum);

}

Stream接口中还存在类似的方法flatMapToDouble、flatMapToLong,使用方法跟flatMapToInt是一样的,这里就不多介绍了,仅罗列一下方法定义:

DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper);

LongStream flatMapToLong(Function super T, ? extends LongStream> mapper);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值