【问题标题】:java helper class for merging/filling elements in list用于合并/填充列表中元素的 java 帮助类
【发布时间】:2016-02-29 12:17:54
【问题描述】:

这是我们代码库中的一种常见模式,当将模型列表从(例如)Thing 映射到 MyModel 时:

List<MyModel> myModelList = new ArrayList<>();
for (Thing thing : things) {
    MyModel myModel = new MyModel(thing.getId());
    if (myModelList.contains(myModel)) {
        myModel = myModelList.get(myModelList.indexOf(myModel));
    } else {
        myModel.setName(thing.getName());
        myModelList.add(myModel);
    }
    myModel.setSomeQuantity(myModel.getSomeQuantity() + thing.getSomeQuantity());
}

(假设 MyModel 有 equals() 和 hashCode() 使用 id 来决定相等)

这可以通过一些不同的方式完成,您可以使用以 id 作为键的地图等。我们可以为它创建一个通用的帮助类,它可以在任何地方使用。

但我想知道的是,在某些 java、apache、spring、google 或其他库中,是否已经有一些帮助类或其他类型的构造以一种有效且干净的方式处理了所有这些问题?

【问题讨论】:

    标签: java list mapping


    【解决方案1】:

    您在List 上同时使用containsindexOf。这两者通常都需要线性搜索,因此应尽可能避免。你绝对不应该像这样在contains 之后直接使用indexOf。你永远不需要这样做

    if (list.contains(x)) 
        x = list.get(list.indexOf(x));
    

    因为你总是可以这样做

    int index = list.indexOf(x);
    if (index >= 0)
        x = list.get(index);
    

    这是更多代码,但避免了两次搜索列表。

    但是,我不喜欢你使用 equalshashCode。通常,equal 对象可以互换处理,而在您的情况下,myModel 的两个版本不同;只有已经在列表中的那一项带有关于名称和总量的额外信息。

    我建议将MyModel 替换为只有两个字段(idname)的不可变类MyModel。然后你可以这样做(假设你使用的是 Java 8)

    Map<MyModel, Double> quantities = new HashMap<>();
    for (Thing thing : things)
        quantities.merge(thing.getModel(), thing.getQuantity(), Double::sum);
    

    【讨论】:

    • 很好的答案!我们还不能使用 java 8,但很快,所以当我们在那里时,我将开始使用这种模式。 :)
    • @TV'sFrank I 在 android 中编程,所以也不能使用 java 8。我发现Map.merge 非常有用,我为它编写了一个静态方法。
    【解决方案2】:

    这听起来更像是Set 的工作,而不是列表。

    不包含重复元素的集合。更正式地说,集合不包含满足 e1.equals(e2) 的元素 e1 和 e2 对,并且最多包含一个空元素。

    Set<MyModel> myModelSet = new HashSet<>();
    for (Thing thing : things) {
        MyModel myModel = new MyModel(thing.getId());
        myModel.setName(thing.getName());
        // copy more fields if nessecary or write a copyFromThing() method  or a constructor that accepts Thing as a parameter in the MyModel class
    
        myModel.setSomeQuantity(myModel.getSomeQuantity() + thing.getSomeQuantity());
        myModelSet.add(myModel);
    }
    

    编辑:问题是,当 MyModel 有更多字段要复制时,该 Set 没有 get 方法,这将是一个问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 2021-11-05
      相关资源
      最近更新 更多