8

I have an ArrayList in Java:

{"deleteItem", "createitem", "exportitem", "deleteItems", "createItems"}

I want to move all string which contains delete to the end of the list, so I would get the next:

{"createitem", "exportitem", "createItems", "deleteItem", "deleteItems"}`

I can create two sublists - one for the words which contain the 'delete' word, and one for the others, and then merge them, but I search for a more efficient way.

Naman
  • 27,789
  • 26
  • 218
  • 353
Or Smith
  • 3,556
  • 13
  • 42
  • 69
  • Define "efficient"? Do you actually mean "elegant"? I have an inkling that performance is not important here, so perhaps maintainability is more important? If you really mean efficient, is space or time more important? – Duncan Jones Apr 07 '14 at 07:31

3 Answers3

13

Use custom Comparator:

List<String> strings = Arrays.asList(
        "deleteItem", "createitem", "exportitem", "deleteItems", "createItems"
        );
Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(final String o1, final String o2) {
        if (o1.contains("delete") && !o2.contains("delete")) {
            return 1;
        }else if (!o1.contains("delete") && o2.contains("delete")) {
            return -1;
        }
        return 0;
    }
};
Collections.sort(strings, comparator);
System.out.println(strings);
Naman
  • 27,789
  • 26
  • 218
  • 353
3

If you want something efficient and need to remove elements in the beginning and middle of a List I would suggest using a LinkedList instead of a array list. That would avoid rewriting the underlying array for each remove operation.

Then, you simply iterate on the list, calling remove and addLast for any string that contains delete.

Of course, this is only OK if there is nothing preventing you from replacing your ArrayList with a LinkedList.

Pierre Rust
  • 2,474
  • 18
  • 15
1

You only want to put the elements with delete at the end of the list so ordering is O(nlogn) while we could do this in one pass, in O(n) (although using a new list). We could create a new LinkedLIst and pass through the original list adding the elements with "delete" at the end and the others at the begginging.

    LinkedList<String> orderedList = new LinkedList<>();
    for(String e:originalList){
        if (e.indexOf("delete")>=0) {
            orderedList.addLast(e);
        } else {
            orderedList.addFirst(e);
        }
    }

This is faster than sorting.

Raul Guiu
  • 2,374
  • 22
  • 37
  • How is it efficient than solution provided by OP ? – Jabir Apr 07 '14 at 07:23
  • Sorting, O(nlogn). We rely inthe sorting implementation of the JVM, is fairly good, we dont need to reinvent the wheel. – Raul Guiu Apr 07 '14 at 07:38
  • But searching is O(n) and is his solution 2 searches and a join make is 3N but in Big Oh notation its O(n) correct me if i am wrong – Jabir Apr 07 '14 at 08:25
  • True, and you only need one search. If you dont care of the order of anything else. – Raul Guiu Apr 07 '14 at 08:37