0

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. 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 explained above will be available.

My question is which scenario is better:

  1. Implement the list interface

  2. Extend the ArrayList class and override the ADD method

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Joro Seksa
  • 1,525
  • 3
  • 18
  • 44
  • I think what you're looking for is called [`HashMap`](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html) – Oceans Sep 11 '15 at 09:56
  • Why should i use Hashmap? – Joro Seksa Sep 11 '15 at 09:57
  • It allows you to add items dynamically and search them based on a key. You can also nest HashMaps to get a tree structure, this should allow you to keep all necessary information together. – Oceans Sep 11 '15 at 10:00
  • Ok give me an example how i store objects in a Hashmap based on the time the object is used and then how i iterate a list :) – Joro Seksa Sep 11 '15 at 10:01
  • You could nest Hashmaps like this: `HashMap>` and to iterate trough a HashMap you can find your answer [here](http://stackoverflow.com/questions/26188532/iterate-through-nested-hashmap). – Oceans Sep 11 '15 at 10:10

5 Answers5

4
  1. Create a class that contains an ArrayList and handles any additional functionality.

I.e. 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.

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).

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I agree with the beginning, but not with the end. Forwarding to a list is better than extending ArrayList, but it's also quite hard to do well (for example, implementing the iterator). I simply don't think the user's class should be a List. It should be a class that uses a list. – JB Nizet Sep 11 '15 at 09:59
  • @JBNizet I agree, implementing `List` is not something that would be done regularly in standard code. – Kayaman Sep 11 '15 at 10:03
1

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).

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.

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
Cinnam
  • 1,892
  • 1
  • 15
  • 23
1

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). 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.

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.

  • The ArrayList class is not final, but not expressly designed and documented for inheritance. This can result in some code fragility as inheritance breaks encapsulation (discussed in Effective Java, 2nd Ed. by 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. Favor composition over inheritance. In this way, your solution will be more robust and easier to maintain than a solution based on inheritance.

scottb
  • 9,908
  • 3
  • 40
  • 56
1

You might try using HashMap<Integer, TrackedObject> where TrackedObject is the class of the Object you're keep track of.

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;
}
user5292387
  • 413
  • 2
  • 7
0

A LinkedHashSet Also can be helpful in your case. You can keep on adding elements to it, it will keep them in insertion order and also will maintain only unique values.

Anptk
  • 1,125
  • 2
  • 17
  • 28