使用java 8流修改列表中对象的属性值

Bha*_*ngi 38 java-8 java-stream

Fruit在arraylist中有一个对象列表,我想将fruitName修改为其复数名称.参考示例:

@Data
@AllArgsConstructor
@ToString
class Fruit {

    long id;
    String name;
    String country;
}

List<Fruit> fruits = Lists.newArrayList();
fruits.add(new Fruit(1L, "Apple", "India"));
fruits.add(new Fruit(2L, "Pineapple", "India"));
fruits.add(new Fruit(3L, "Kiwi", "New Zealand"));

Comparator<Option> byNameComparator = (e1, e2) -> e1.getName().compareToIgnoreCase(e2.getName());

fruits = fruits.stream().filter(fruit -> "India".equals(fruit.getCountry()))
            .sorted(byNameComparator).collect(Collectors.toList());

List<Fruit> fruitsWithPluralNames = Lists.newArrayList();
for (Fruit fruit : fruits) {
    fruit.setName(fruit.getName() + "s");
    fruitsWithPluralNames.add(fruit);
}

System.out.println(fruitsWithPluralNames);

// which prints [Fruit(id=1, name=Apples, country=India), Fruit(id=2, name=Pineapples, country=India), Fruit(id=3, name=Kiwis, country=New Zealand)]
Run Code Online (Sandbox Code Playgroud)

我们有没有办法使用java8流实现相同的行为?

Ser*_*tin 73

如果您想创建新列表,请使用Stream.map方法:

List<Fruit> newList = fruits.stream()
    .map(f -> new Fruit(f.getId(), f.getName() + "s", f.getCountry())
    .collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)

如果您想修改当前列表,请使用Collection.forEach:

fruits.forEach(f -> f.setName(f.getName() + "s"))
Run Code Online (Sandbox Code Playgroud)


Apo*_*los 20

你可以使用forEach.根本没有流:

fruits.forEach(fruit -> fruit.setName(fruit.getName() + "s"));
Run Code Online (Sandbox Code Playgroud)


Sri*_*ram 11

你可以peek用来做那件事.

List<Fruit> newList = fruits.stream()
    .peek(f -> f.setName(f.getName() + "s"))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • Peek方法只应用于调试.API注意:此方法主要用于支持调试,您希望在元素流经管道中的某个点时查看这些元素:参考:https://docs.oracle.com/javase/8/docs/api/java /util/stream/Stream.html#peek-java.util.function.Consumer- (8认同)
  • 我不明白为什么这个操作“主要”是为了调试。我不明白为什么 Java API 会有“主要”用于调试的代码。该操作就在那里,可以用于开发人员认为合适的任何操作。当然,开发人员必须了解它的工作原理并正确使用它。对于这个问题,forEach 是一个更好的答案,但是当你想继续流时,peek 更适合(forEach 在这种情况下甚至不起作用)。 (3认同)

小智 5

只是为了修改对象集合中的某些属性,您可以直接将 forEach 与集合一起使用,如下所示

collection.forEach(c -> c.setXyz(c.getXyz + "a"))
Run Code Online (Sandbox Code Playgroud)