【问题标题】:How can I just print a single object and not it's children?我怎样才能只打印一个对象而不是它的孩子?
【发布时间】:2020-10-29 16:25:52
【问题描述】:

我的目标是允许用户修改其他对象列表中的对象元素。首先,我需要搜索元素“名称”,以便可以识别需要修改的具有该名称的特定对象。我的代码在一定程度上完成了这项工作,但是,我有 3 个对象,其中 2 个对象“嵌套”在一个对象中。所以我处于困境,如果我搜索父对象,它会显示父对象的结果,它是子对象,如果我搜索子对象,它会返回 null。我该如何解决这个问题,以便它只返回具有我搜索的元素名称的特定对象?我想单独对待他们每个人。

  1. xml 的格式无法更改,因为结构是我所限制的

我不确定问题是否与我最初将 xml 文件解析为 java 对象的方式有关

主类

public class Main {
    public static void main(String[] args) throws IOException, JAXBException {

        File file = new File("items.xml");
        Scanner scan = new Scanner(System.in);

        JAXBContext context = JAXBContext.newInstance(Items.class);
        Unmarshaller un = context.createUnmarshaller();
        Items itemData = (Items) un.unmarshal(file);

        List<Item> items = itemData.getItem();

        System.out.println("'\n\n------------- Options ---------------");
        System.out.println("\n1. Search Items by Group");
        System.out.println("\n2. Modify Movie");
        int choice = scan.nextInt();
        scan.nextLine();

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

            Optional<Item> item = items.stream()
                    .filter(x -> x.getName().equals(search))
                    .findFirst();

            System.out.println(item.toString());

        }

        else{
            System.out.println("You entered an invalid option!");
        }
    }
}

物品类别

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";
    }
}

物品类

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 ;
    }
}

XML 文件

<items> 
      <item>
            <dataType>Number</dataType>
            <name>Rush Hour</name>
            <data>1</data>
            <group>Comedy</group>
      </item>
      <item>
            <dataType>Number</dataType>
            <name>Harry Potter</name>
            <data>2</data>
            <group>Fiction</group>
            <items>
                  <item>
                        <dataType>Number</dataType>
                        <name>Harry Potter and the Goblet Of Fire</name>
                        <data>3</data>
                        <group>Fiction</group>
                  </item>
                  <item>
                        <dataType>Number</dataType>
                        <name>Harry Potter and the Chamber of secrets</name>
                        <data>4</data>
                        <group>Fiction</group>
                  </item>
            </items>
      </item>
      <item>
            <dataType>Number</dataType>
            <name>Men In Black</name>
            <data>5</data>
            <group>Action</group>
      </item>
      <item>
            <dataType>Number</dataType>
            <name>Coming to America</name>
            <data>6</data>
            <group>Comedy</group>
      </item>
</items>

【问题讨论】:

  • private Items items; 是什么,您希望将其作为类似 private List&lt;Item&gt; items; 的项目列表。
  • 我有另一个班级的名单。我会更新我的帖子以显示该课程。
  • 只需从您的 toString 中删除项目,或添加第二种方法以返回没有项目的值
  • @Stultuske toString 有助于打印子对象,因为没有它,子项将无法打印。
  • @SharleneRoberts 并且因为您想在没有“子”项目的情况下打印它,所以这有点重要。或者,正如我所说:如果您想将项目保留在 toString 中,请创建第二个返回字符串的方法,并在您不希望打印项目的地方打印它

标签: java xml-parsing data-modeling


【解决方案1】:

您也可以修改代码以搜索嵌套项。请从以下代码中获取帮助:

            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();

这将有助于搜索 2 级嵌套 对象中的元素。

当您搜索哈利波特与密室时,它会给出一个与该名称对应的哈利波特对象。

Optional[
    DataType: Number
    Name: Harry Potter and the Chamber of secrets
    Data: 4
    Group: Fiction
    Items: null
]

【讨论】:

  • 对于这篇文章,这个答案不是我想要的,因为就像我提到的I'd like to treat each of them individually.
  • 好的,那么你就可以使用 flatMap 了。请参考更新后的答案。
猜你喜欢
  • 2022-11-04
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多