Java 8流-修改组中的所有元素

时间:2018-12-01 03:35:29

标签: java java-8 java-stream

我有一个Class A的对象

class A {
    String code;
    long timestamp;
    long largestTimestamp;
}

我必须为每个对象填充最大的Timestamp字段(使用相同代码的对象组中最大的“时间戳”值)。我可以按照以下两个步骤进行操作-

Map<String, Long> largestTimestampMap = list.stream().collect(Collectors.toMap(A::getCode, A::getTimestamp, Long::max));
list.forEach(a -> a.setLargestTimestamp(largestTimestampMap.get(a.getCode())));

有没有办法将它们组合成单个流链?

3 个答案:

答案 0 :(得分:4)

是的,您可以将它们组合为一条管道,如下所示:

list.stream()
     .map(a -> new A(a.getCode(), a.getTimestamp(),
                list.stream()
                    .filter(b -> a.getCode().equals(b.getCode()))
                    .mapToLong(A::getTimestamp)
                    .max().getAsLong()))           
     .collect(Collectors.toList());

或者如果您想避免创建新列表,而是像示例中那样修改现有列表,则使用replaceAll

list.replaceAll(a -> new A(a.getCode(), a.getTimestamp(),
                        list.stream()
                                .filter(b -> a.getCode().equals(b.getCode()))
                                .mapToLong(A::getTimestamp)
                                .max().getAsLong()));

但是,我建议避免这种方法:

1),因为它的性能比当前的实现要差,因此此解决方案要求再次遍历list中的forEach元素。而您所展示的Map方法只需要一个get调用,我们都知道在地图中查找的速度有多快。

2)还有更多代码。

是的,您可以将map中间操作中的代码重构为一种方法,以使其看起来更短,但最终仍然更长。

有时候最好的方法需要两行或更多行,在这种情况下,最好继续使用您的方法。

答案 1 :(得分:3)

您可能只是在寻找(如果为每个对象填充maximumTimestamp字段意味着为整个列表保存相同的largestTimeStamp):

// find the largest timestamp
long largestTimeStamp = list.stream()
        .mapToLong(A::getTimestamp)
        .max()
        .orElse(Long.MIN_VALUE);

// iterate through the list to set its value
list.forEach(a -> a.setLargestTimestamp(largestTimeStamp));

如果必须在一行代码下执行此操作,则可以使用(已编辑,以与Aomine在注释中阐明的现有代码保持一致):

List<A> output = list.stream()
        .map(a -> new A(a.getCode(), a.getTimestamp(),
                list.stream().filter(b -> a.getCode().equals(b.getCode()))
                        .mapToLong(A::getTimestamp).max().orElse(a.getTimestamp())))
        .collect(Collectors.toList());

答案 2 :(得分:0)

只是一个不同的想法,但您不能像下面所示那样构造A类

class A {
  String code;
  long timeStamp;
  TimeStampWrapper timeStampWrapper;
}

class TimeStampWrapper {
  long maxTimeStamp;
  long minTimeStamp;
  ...
}

使用这种方法,您只需要遍历1个流,而只需一次设置操作即可设置maxTimeStamp,minTimeStamp等。