【问题标题】:Should i implement List interface or extend ArrayList class in Java我应该在 Java 中实现 List 接口还是扩展 ArrayList 类
【发布时间】:2015-12-07 20:19:50
【问题描述】:

我正在开发一个应用程序,作为背景,我需要监视用户对特定对象的活动,然后当它们被可视化时,它们需要根据用户使用它们的顺序进行排序(最后使用的对象必须是例如显示在网格的第一行。)

因此,如果我有一个 Arraylist,我在其中存储用户正在处理的对象,以便添加最后使用的对象,我需要检查它是否已经在列表中,然后将其移动到第一个位置。如果对象不存在,我只需将其添加到列表的第一个位置。

因此,我不想做所有这些步骤,而是想制作自己的列表,上面解释的逻辑可用。

最后我的问题是(希望不是基于意见)哪种情况更好:

  1. 实现列表界面
  2. 扩展 ArrayList 类并覆盖 ADD 方法

提前 10 倍。

【问题讨论】:

  • 我想你要找的东西叫HashMap
  • 为什么要使用Hashmap?
  • 它允许您动态添加项目并根据键搜索它们。您还可以嵌套 HashMaps 以获得树结构,这应该允许您将所有必要的信息放在一起。
  • 好的,给我一个例子,我如何根据对象的使用时间将对象存储在 Hashmap 中,然后我如何迭代列表:)
  • 您可以像这样嵌套 Hashmap:HashMap<String, HashMap<Time, Object>> 并通过 HashMap 进行迭代,您可以找到答案 here

标签: java collections polymorphism


【解决方案1】:

您可以尝试使用HashMap<Integer, TrackedObject>,其中 TrackedObject 是您要跟踪的对象的类。

当你的用户使用一个对象时,做

void trackObject(TrackedObject object)
{
  int x = hashMap.size();
  hashMap.add(Integer.valueOf(x), object);
}

那么当你想按使用顺序读出被跟踪对象时:

TrackedObject[] getOrderedArray()
{
  TrackedObject[] array = new TrackedObject[hashMap.size()];
  for(int i = 0; i < hashMap.size(); i++)
  {
    array[i] = hashMap.get(Integer.valueOf(i));
  }
  return array;
}

【讨论】:

    【解决方案2】:

    我认为LinkedHashMap 已经满足了您的需求 - 它按照插入或上次访问的顺序保留元素(这由其中一个构造函数中的参数 accessOrder 确定)。

    https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html

    编辑

    我没有足够的声誉来发表评论,所以我把它放在这里:你实际上不需要地图,所以 Venkatesh 的 LinkedHashSet 建议更好。

    你可以这样做:

    <T> void update(Set<T> set, T value) {
            set.remove(value);
            set.add(value);
    }
    

    然后

        LinkedHashSet<String> set = new LinkedHashSet<>();
        update(set, "a");
        update(set, "b");
        update(set, "c");
        update(set, "a");
    
        Iterator<String> it = new LinkedList<String>(set).descendingIterator();
    
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    

    输出:

    a
    c
    b
    

    【讨论】:

      【解决方案3】:

      LinkedHashSet 对您的情况也有帮助。您可以继续向其中添加元素,它会将它们保持在 插入顺序 中,并且只会保持 唯一 值。

      【讨论】:

      • 我希望 LAST 添加在第一个索引处
      • 错过了,在这种情况下,Cinnam 和 Kayaman 提到的 LinkedHashMap 应该适合你。
      • 那么我可以让linkedhashmap反转插入顺序吗?
      【解决方案4】:

      因此,我不想做所有这些步骤,而是想在哪里创建自己的列表 上面解释的逻辑将可用。

      我会尝试重构您的设计参数(如果可以的话),以便能够使用现有的 Java 集合框架类(可能是链接集合类型)。作为 Collections Framework 的一部分,它们已经优化和维护了多年(因此效率可能已经接近最佳),您不必担心自己维护它。

      在您提供的两个选项中,可能都不是最简单或最好的。

      • 听起来你不能扩展 AbstractList(作为实现 List 的一种方式),所以你需要做很多轮子改造。

      • ArrayList 类不是最终的,但不是为继承而明确设计和记录的。这会导致一些代码脆弱,因为继承破坏了封装(在 Effective Java, 2nd Ed. by J. Bloch 中讨论过)。此解决方案可能不是最好的方法。

      在这些选项中,如果您无法重构设计以允许直接使用 Collection 类,则编写一个将 List(或其他 Collection)封装为实例字段的类并向其添加检测。 优先考虑组合而不是继承。这样,您的解决方案将比基于继承的解决方案更健壮且更易于维护。

      【讨论】:

        【解决方案5】:
        1. 创建一个包含ArrayList 并处理任何其他功能的类。

        即更喜欢组合而不是继承(在这种情况下,实现接口)。也可以让该类针对相关案例实现List,并将(相关)操作定向到内部的ArrayList

        还要注意LinkedHashMap 支持插入顺序(默认)和迭代的访问顺序,如果您不需要List(或者如果您可以适当地用Map 替换它)。

        【讨论】:

        • 我同意开头,但不同意结尾。转发到列表比扩展 ArrayList 更好,但也很难做好(例如,实现迭代器)。我根本不认为用户的类应该是一个列表。它应该是一个使用列表的类。
        • @JBNizet 我同意,实现List 不是在标准代码中定期完成的事情。
        猜你喜欢
        • 2018-11-17
        • 2012-12-10
        • 2021-03-17
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多