【问题标题】:How can I use a map to modify existing elements in a stream?如何使用地图修改流中的现有元素?
【发布时间】:2020-07-09 23:47:08
【问题描述】:

我搜索了一个对象,并且该对象存储在流中。我想让用户能够修改现有流中的元素并使用修改后的元素更新现有列表,而不是完全创建一个新列表。问题与one 类似,只是用户将修改后的元素添加到新列表中

这是我目前所拥有的。我目前收到此错误

运算符'+'不能应用于'void'、'void'

如果您需要完整的代码,或包含其他类,请告诉我。

主类

else if (choice == 2){
            System.out.println("\nEnter the name of the movie you would like to modify (Case Sensitive): ");
            String search = scan.nextLine();

            Optional<Item> item = items.stream()
                    .map(x->{
                        if(x.getItems()==null){
                            return Collections.singletonList(x);
                        }
                        x.getItems().getItem().add(x);
                        return x.getItems().getItem();
                    })
                    .flatMap(Collection::stream)
                    .filter(x -> x.getName().equals(search))
                    .peek(x-> x.setItems(null))//Peek exists mainly to support debugging
                    .findFirst();
            System.out.println(item.toString());

            System.out.println("\nEnter the new datatype of the movie (Number): ");
            String userChoice = scan.nextLine();

            System.out.println("\nEnter the new name of the movie: ");
            String userChoice1 = scan.nextLine();

            System.out.println("\nEnter the new data ID for the movie (Number): ");
            int userChoice2 = scan.nextInt();
            scan.nextLine();

            System.out.println("\nEnter the new group for the movie: ");
            String userChoice3 = scan.nextLine();

            Collection::stream =
                    item.map(s -> s.setDataType(userChoice) + s.setName(userChoice1) + s.setData(userChoice2) + s.setGroup(userChoice3));
        }

物品类

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "items")
public class Items {
    private List<Item> item;

    @XmlElement(name = "item")
    public List<Item> getItem(){
        return item;
    }

    public void setItem(List<Item> itemList){
        this.item = itemList;
    }

    @Override
    public String toString() {
        return "\n" + item ;
    }
}

物品类别

import javax.xml.bind.annotation.XmlElement;

public class Item {
    private String dataType;
    private String name;
    private int data;
    private String group;
    private Items items;

    @XmlElement
    public String getDataType(){
        return dataType;
    }
    public void setDataType(String dataType){
        this.dataType = dataType;
    }

    @XmlElement
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }

    @XmlElement
    public int getData(){
        return data;
    }
    public void setData(int data){
        this.data = data;
    }

    @XmlElement
    public String getGroup(){
        return group;
    }
    public void setGroup(String group){
        this.group = group;
    }

    public Items getItems() {
        return items;
    }

    public void setItems(Items items) {
        this.items = items;
    }

    @Override
    public String toString() {
        return
                "\n\tDataType: " + dataType +
                "\n\tName: " + name +
                "\n\tData: " + data +
                "\n\tGroup: " + group +
                "\n\tItems: " + items + "\n";
    }

    public String singleObject(){
        return
                "\n\tDataType: " + dataType +
                "\n\tName: " + name +
                "\n\tData: " + data +
                "\n\tGroup: " + group;
    }

}

【问题讨论】:

  • 你能发布Item类吗?
  • @marc Item 和 Items class(Just incase) 已发布
  • 为了您的信息,Items 类引用Item 类和Item 类引用Items 类。这称为循环依赖,应该避免。
  • 引用是为了处理解析另一个对象中的嵌套对象。在那种情况下仍然很糟糕吗?

标签: java


【解决方案1】:

我看到在您的主要功能中,您要求用户提供电影的名称,然后提供要修改的字段。所以在询问用户所有问题后,可以使用如下操作:

items.stream()
     // search for the movie by name
     .filter(x -> x.getName().equals(search))
     .findFirst()
     // if present then modify it
     .ifPresent(i -> {
        i.setDataType(userChoice);
        i.setName(userChoice1);
        i.setData(userChoice2);
        i.setGroup(userChoice3);
        i.setItems(null);
        });

这样列表就被原地修改了。

【讨论】:

  • 我明白了,我之前发表过一篇文章,询问解决此问题的最佳方法是什么,并得到了使用地图的建议,因此我采用了上述方法。谢谢,我试试看效果如何
  • 是的,通常您使用map 来创建一个新列表并使用forEach 来修改一个列表。但在您的情况下,只有一个元素需要修改,因此您可以使用 findFirstifPresent 而不是 forEach
  • 我可能误解了你的意思,只有一个元素需要修改。该列表包含多个对象(电影),每个对象都包含我向用户询问的字段。所以用户可以选择他们首先想要修改的电影,然后继续修改它,但是是的,一次只能修改一部电影。这是我的github 的链接,其中包含显示结构的 xml 文件
【解决方案2】:

item.map() 语句中,您正在调用返回 void 的 setter,因此您遇到了问题。 Void 不是 map 方法的有效返回类型。 + 运算符也不能应用于 void 操作数。

几个观察结果

  1. if(choice == 2)
  • 在这里您应该只执行一项修改列表中存在的电影的任务,如果列表中缺少电影,请通知用户这一点。
  1. Items class 包含 List&lt;Item&gt;
  • 现在无需在 Item 类中添加 Item。

下面是我试过的示例代码

它在Items中找到用户输入的电影名称并在那里修改它 而不是创建一个全新的列表。

. items.getItem().stream()  
.filter(x -> x.getName.equals(search))
.forEach(x -> {x.setName(userInputName); x.setDatType(userInputDataType)});

【讨论】:

  • 我试过这个,但使用 getter 我无法输入用户输入作为参数,item.map(s -&gt; s.getDataType(userChoice) 其中 userChoice 不是预期参数
  • 就功能而言,您要实现什么目标?那条特定的行是什么意思?
  • 我正在尝试修改流中元素的值。为此,用户必须首先输入新值。之后,必须收集这些值并将其映射到位于流中的现有值,从而将旧值修改为新用户输入的值。该特定行旨在获取新的用户输入并将它们传递给元素以进行更改
  • 几个观察 1) if(choice == 2) 在这里你应该只做一个修改列表中存在的电影的任务,如果列表中缺少电影通知用户这一点。 2) Items 类包含 List,现在不需要在 Item 类中添加 Items。不管怎样,下面是我尝试过的示例代码,它找到用户在 Items 中输入的电影名称并在那里修改它,而不是创建一个全新的列表。希望它能为你完成这项工作。 items.getItem().stream().filter(x -> x.getName.equals(search)).forEach(x -> {x.setName(userInputName); x.setDatType(userInputDataType)});
  • 谢谢。我编辑了您的原始答案并添加了评论中的代码。希望这可以帮助其他可能遇到它的人:)
【解决方案3】:

您编写了非常复杂的代码。几个观察:

  1. if(choice == 2) 在这里您应该只执行一项修改列表中存在的电影的任务,如果列表中缺少电影,请通知用户而不是添加它。
  2. Items 类包含 Item 列表,现在无需在 Item 类中添加 Items,除非这些是您希望在 DB 中持久化的实体类。

反正下面是sn-p代码,希望对你有帮助。

items.getItem().stream().filter(x -> x.getName.equals(search)).forEach(x -> {x.setName(userInputName); x.setDatType(userInputDataType)});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多