简体   繁体   English

我应该在Java中实现List接口还是扩展ArrayList类?

[英]Should i implement List interface or extend ArrayList class in Java

I am developing an application where as a background i need to monitor the user activity on particular objects and later when they are visualized they need to be sorted based on the order of which the user used them ( the last used object must be visualized on the first row of a grid for example.) 我正在开发一个应用程序,在该应用程序中,我需要作为背景来监视用户在特定对象上的活动,稍后在可视化它们时,需要根据用户使用它们的顺序对它们进行排序(最后使用的对象必须在对象上可视化例如,网格的第一行。)

So if i have an Arraylist where i store the objects which the user is dealing with in order to add the last used object i need to check if it is already in the list and then move it at the first position. 因此,如果我有一个Arraylist,我要在其中存储用户要处理的对象以添加上次使用的对象,则需要检查它是否已经在列表中,然后将其移动到第一个位置。 If the object is not there i simply add it at the first position of the list. 如果对象不存在,我只需将其添加到列表的第一个位置。

So instead of doing all these steps i want to make my own list where the logic exlained above will be available. 因此,我不想做所有这些步骤,而是要列出上面介绍的逻辑,以列出自己的列表。

And finally my question is (hopefully it is not opinion based) which scenario is better: 最后,我的问题是(希望这不是基于观点的)哪种方案更好:

  1. Implement the list interface 实现列表界面
  2. Extend the ArrayList class and override the ADD method 扩展ArrayList类并覆盖ADD方法

10x in advance. 提前10倍。

  1. Create a class that contains an ArrayList and handles any additional functionality. 创建一个包含ArrayList并处理所有其他功能的类。

Ie prefer composition over inheritance (and in this case, implementing an interface). 即,相对于继承,它更喜欢组合(在这种情况下,是实现接口)。 It's also possible to have that class implement List for relevant cases and just direct the (relevant) operations to the ArrayList inside. 也可以让该类针对相关情况实现List ,并将(相关)操作直接定向到内部的ArrayList

Also note that LinkedHashMap supports insertion order (default) and access order for iteration, if you don't need a List (or if you can suitably replace it with a Map ). 还要注意,如果不需要List (或者可以使用Map适当替换它), LinkedHashMap支持插入顺序(默认)和访问顺序(用于迭代)。

I think LinkedHashMap already does what you need - it keeps the elements in the order they were inserted or last accessed (this is determined by the parameter accessOrder in one of the constructors). 我认为LinkedHashMap已经accessOrder您的需要-可以按插入或最后访问的顺序保留元素(这由构造函数之一中的参数accessOrder确定)。

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

EDIT 编辑

I don't have enough reputation to comment, so I'm putting it here: You don't actually need a map, so Venkatesh's LinkedHashSet suggestion is better. 我没有足够的声誉来发表评论,所以在这里输入:您实际上不需要地图,因此Venkatesh的LinkedHashSet建议更好。

You can do something like this: 您可以执行以下操作:

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

and then 接着

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

Output: 输出:

a
c
b

So instead of doing all these steps i want to make my own list where the logic explained above will be available. 因此,我不想做所有这些步骤,而是要列出自己的列表,上面列出的逻辑将可用。

I would try to refactor your design parameters (if you can) in order to be able to use the existing Java Collection Framework classes (perhaps a linked collection type). 我将尝试重构您的设计参数(如果可以),以便能够使用现有的Java Collection Framework类(也许是链接的集合类型)。 As a part of the Collections Framework, these have been optimized and maintained for years (so efficiency is likely already nearly optimal), and you won't have to worry about maintaining it yourself. 作为Collections Framework的一部分,它们已经进行了优化和维护多年(因此效率可能已经接近最佳状态),而您不必担心自己维护它。

Of the two options you give, it is possible that neither is the easiest or best. 在您提供的两个选项中,最简单或最好的选择都不是。

  • It doesn't sound like you'll be able to extend AbstractList (as a way of implementing List) so you'll have a lot of wheel reinvention to do. 听起来您不能扩展AbstractList (作为实现List的一种方式),所以您将需要进行很多工作。

  • The ArrayList class is not final, but not expressly designed and documented for inheritance. ArrayList类不是最终的,但没有明确设计和记录继承。 This can result in some code fragility as inheritance breaks encapsulation (discussed in Effective Java, 2nd Ed. by J. Bloch). 由于继承破坏了封装,这可能会导致某些代码易碎(在有效Java中,由J. Bloch撰写的第二版中讨论)。 This solution may not be the best way to go. 此解决方案可能不是最佳方法。

Of the options, if you can't refactor your design to allow use of the Collection classes directly, then write a class that encapsulates a List (or other Collection) as an instance field and add instrumentation to it. 在这些选项中,如果您不能重构设计以允许直接使用Collection类,则编写一个将List (或其他Collection)封装为实例字段的类,并为其添加检测功能。 Favor composition over inheritance. 优先考虑组成而不是继承。 In this way, your solution will be more robust and easier to maintain than a solution based on inheritance. 这样,您的解决方案将比基于继承的解决方案更加健壮和易于维护。

You might try using HashMap<Integer, TrackedObject> where TrackedObject is the class of the Object you're keep track of. 您可以尝试使用HashMap<Integer, TrackedObject> ,其中TrackedObject是您要跟踪的对象的类。

When your user uses an object, do 当用户使用对象时,请执行

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

then when you want to read out the tracked objects in order of use: 然后,当您想按使用顺序读出被跟踪对象时:

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

A LinkedHashSet Also can be helpful in your case. LinkedHashSet在您的情况下也可能会有所帮助。 You can keep on adding elements to it, it will keep them in insertion order and also will maintain only unique values. 您可以继续向其添加元素,这将使它们保持插入顺序,并且仅保留唯一值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM