Java 8 修改流元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38302531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:11:34  来源:igfitidea点击:

Java 8 modify stream elements

javajava-8java-stream

提问by Zyga

I wanted to write pure function with Java 8 that would take a collection as an argument, apply some change to every object of that collection and return a new collection after the update. I want to follow FP principles so I dont want to update/modify the collection that was passed as an argument.

我想用 Java 8 编写纯函数,它将集合作为参数,对该集合的每个对象应用一些更改,并在更新后返回一个新集合。我想遵循 FP 原则,所以我不想更新/修改作为参数传递的集合。

Is there any way of doing that with Stream API without creating a copy of the original collection first (and then using forEach or 'normal' for loop)?

有没有办法使用 Stream API 做到这一点,而无需先创建原始集合的副本(然后使用 forEach 或“普通”for 循环)?

Sample object below and lets assume that I want to append a text to one of the object property:

下面的示例对象,让我们假设我想将文本附加到对象属性之一:

public class SampleDTO {
    private String text;
}

So I want to do something similar to below, but without modifying the collection. Assuming "list" is a List<SampleDTO>.

所以我想做一些类似于下面的事情,但不修改集合。假设“列表”是一个List<SampleDTO>.

list.forEach(s -> {
    s.setText(s.getText()+"xxx");
});

采纳答案by Eran

You must have some method/constructor that generates a copy of an existing SampleDTOinstance, such as a copy constructor.

您必须有一些方法/构造函数来生成现有SampleDTO实例的副本,例如复制构造函数。

Then you can mapeach original SampleDTOinstance to a new SampleDTOinstance, and collectthem into a new List:

然后你可以把map每个原始SampleDTO实例都变成一个新SampleDTO实例,并将collect它们变成一个新实例List

List<SampleDTO> output = 
    list.stream()
        .map(s-> {
                     SampleDTO n = new SampleDTO(s); // create new instance
                     n.setText(n.getText()+"xxx"); // mutate its state
                     return n; // return mutated instance
                 })
       .collect(Collectors.toList());

回答by soorapadman

To make this more elegant way I would suggest create a Methodwith in the class.

为了使这种更优雅的方式,我建议Method在课堂上创建一个with 。

 public class SampleDTO {
 private String text;
public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

public SampleDTO(String text) {
    this.text = text;
}

public SampleDTO getSampleDTO() {
    this.setText(getText()+"xxx");
    return this;
}
    }

and add it like:

并将其添加为:

List<SampleDTO> output =list.stream().map(SampleDTO::getSampleDTO).collect(Collectors.toList();

回答by Theresa Forster

Streams are immutable like strings so you cannot get around needing to create a new stream/list/array

流像字符串一样是不可变的,因此您无法避免需要创建新的流/列表/数组

That being said you can use .Collect() to return a new collection post change so

话虽如此,您可以使用 .Collect() 返回一个新的集合后更改

List<Integer> result = inList.stream().map().Collect()

回答by Rodney P. Barbati

I think it would be better, especially if doing multi-threaded work, to stream the original list into a new modified list or whatever else is desired.

我认为将原始列表流式传输到新的修改列表或其他任何需要的列表会更好,尤其是在进行多线程工作时。

The new list or map or whatever other structure you desire can be created as part of the streaming process.

新列表或地图或您想要的任何其他结构可以作为流处理过程的一部分创建。

When the streaming process is completed, simply swap the original with the new.

流处理完成后,只需将原始文件与新文件交换即可。

All of this should occur in a synchronized block.

所有这些都应该发生在一个同步块中。

In this manner, you get the maximum performance and parallelism for the reduce or whatever it is you are doing, and finish with an atomic swap.

通过这种方式,您可以获得最大的性能和并行度,无论您正在做什么,并以原子交换结束。