【问题标题】:How do I make two different ArrayLists reference the same object when Parsing a Json file解析Json文件时如何使两个不同的ArrayLists引用同一个对象
【发布时间】:2021-12-12 06:21:20
【问题描述】:

我正在尝试解析一个 json 数据文件,该文件在两个不同的 ArrayLists 中有一个单一的对象:

{
  "TA": [
    {
      "firstname": "John",
      "lastname": "Smith"
    },
    {
      "firstname": "Jane",
      "lastname": "Doe"
    }
  ],
  "Student": [
    {
      "firstname": "John",
      "lastname": "Smith"
    },
    {
      "firstname": "Kevin",
      "lastname": "White"
    }
  ]
}

我当前的解析方法只是为每个对象创建一个新的 Person 对象并将它们添加到每个 List 对象,但我希望我的 Person 对象 John Smith 仅是“TA”列表和“Student”列表引用的单个对象.我该怎么做呢?

【问题讨论】:

  • 好吧,你可以创建自己的解析器并定义一个equals 方法来检查新创建的对象是否已经存在。
  • 答案取决于您使用的 JSON 库。是哪一个?
  • 你能添加一些你当前解析的代码吗?我认为@shmosel 有使用地图的正确方法(也可以使用 HashSet),但他的示例专门针对您显然没有使用的杰克逊?
  • @magicmn 您必须遍历集合才能找到内部值。

标签: java json parsing


【解决方案1】:

助教和学生名单是两个不同的名单。如果您定义每个列表并使用相同的对象(人)填充它们,是的,它们将指向相同的对象。那是面向对象的方法。

解析 Json 并期望在两个数组中具有相同的人员对象是不可能的(假设人员对象将由解析器创建)。解析器将单独处理每个数组,因此您的个人对象不会相同。

有一种方法可以做到这一点,即在静态类中定义 person 对象。这样,您将始终获得 person 对象的相同实例。

在您的情况下,您必须为每个变体(名字姓氏)创建一个静态人员对象

【讨论】:

    【解决方案2】:

    如果您想降低内存使用量,可以使用静态工厂方法来实习实例。假设您使用 Jackson:

    class Person {
        private static Map<Person, Person> cache = new HashMap<>();
    
        @JsonCreator
        public static Person create(
                @JsonProperty("firstname") String firstname,
                @JsonProperty("lastname") String lastname) {
            Person person = new Person(firstname, lastname);
            return cache.computeIfAbsent(person, Function.identity());
        }
    
        final String firstname;
        final String lastname;
    
        private Person(String firstname, String lastname) {
            this.firstname = firstname;
            this.lastname = lastname;
        }
    
        @Override
        public boolean equals(Object o) {
            return o instanceof Person
                    && Objects.equals(((Person)o).firstname, this.firstname)
                    && Objects.equals(((Person)o).lastname, this.lastname);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(this.firstname, this.lastname);
        }
    }
    

    【讨论】:

    • 我认为构造函数create 的两个参数都假设添加属性名称如下:public static Person create(@JsonProperty("firstname") String firstname, @JsonProperty("lastname") String lastname) {...}
    • @LHCHIN 谢谢,我本来打算这样做的。尽管您可以使用 ParameterNamesModule 来避免它。
    • 既然用了HashMap,我觉得还是把hashCode()方法高亮而不是equals比较好,因为HashMap会使用hashCode来区分map的key。
    • @efmalik 公平点。已更新。
    猜你喜欢
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2023-04-07
    相关资源
    最近更新 更多