lannyf
lannyf

Reputation: 11035

How to build an ArrayList according to the position of each data item

Let's say there is a collection of data of type: {position: i, object}

How do I build an ArrayList which has the data in the order determined by position but without gaps in the ArrayList?

For example, if the data looks like this:

[{position: 3, object3}, {position: 5, object5}, {position: 2, object2}] 

I would like an ArrayList like this:

arrayList[0] == object2;
arrayList[1] == object3;
arrayList[2] == object5;

Upvotes: 1

Views: 239

Answers (5)

Sahar Avr
Sahar Avr

Reputation: 1168

Great question. Assuming Comparable is implementable, you can use the compareTo method (just like in Strings).

So, for example, your custom comparator could look like the following:

public class CustomComparator implements Comparator<MyObject> {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        if (o1.position < o2.position)
            return -1;
        return 0;
    }
}

And to sort your ArrayList, you'll need to call:

Collections.sort(arrayList, new CustomComparator());

Upvotes: 1

OscarRyz
OscarRyz

Reputation: 199264

In addition to sort and/or TreeSet which might be the best choices, you may create a method to insert in order:

public static void add( List<YourClass> list, YourClass o ) {
    for ( int i = 0 ; i < list.size(); i++ ) {
        if ( list.get(i).position() > o.position() ) {
            list.add(i, o);
            return;
        }
    }
    list.add(o);
}

Full demo program:

import java.util.List;
import java.util.ArrayList;
class YourClass {
    private int position;
    private String data;
    public YourClass( int position, String data ) {
        this.position = position;
        this.data = data;
    }
    public int position() {
        return position;
    }
    public String toString() {
        return String.format("{position: %d %s}", position, data);
    }
}
class Main {
    public static void main( String ... args ) {
        List<YourClass> list = new ArrayList<>();

        add( list, new YourClass(3, "object 3"));
        add( list, new YourClass(5, "object 5"));
        add( list, new YourClass(2, "object 2"));
        add( list, new YourClass(1, "object 1"));
        System.out.println(list);
    }
    public static void add( List<YourClass> list, YourClass o ) {
        for ( int i = 0 ; i < list.size(); i++ ) {
            if ( list.get(i).position() > o.position() ) {
                list.add(i, o);
                return;
            }
        }
        list.add(o);
    }
}

Output:

java Main
[{position: 1 object 1}, {position: 2 object 2}, {position: 3 object 3}, {position: 5 object 5}]

Upvotes: 1

cahen
cahen

Reputation: 16676

You call do this with a TreeSet and a Comparator:

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

class KeyPair<T> {

    private final int position;
    private final T value;

    public KeyPair(int position, T value) {
        this.position = position;
        this.value = value;
    }

    public int getPosition() {
        return position;
    }

    public T getValue() {
        return value;
    }

    @Override
    public String toString() {
        return position + " => " + value;
    }
}

public class Main {

    public static void main(String[] args) {
        TreeSet<KeyPair> set = new TreeSet<>((o1, o2) -> o1.getPosition() - o2.getPosition());

        set.add(new KeyPair<>(5, "x"));
        set.add(new KeyPair<>(1, "y"));
        set.add(new KeyPair<>(2, "z"));
        set.add(new KeyPair<>(7, "a"));
        set.add(new KeyPair<>(6, "b"));
        set.add(new KeyPair<>(0, "c"));

        set.stream().forEach(System.out::println);
    }

}

Output:

0 => c
1 => y
2 => z
5 => x
6 => b
7 => a

And if you need an ArrayList instead of a TreeSet you can do this:

List<KeyPair> list = new ArrayList<>();
list.addAll(set);

The good thing about this approach is that at any point in time you have the collection sorted by position if compared with the approach of only sorting in the end.

Upvotes: 1

ThomasS
ThomasS

Reputation: 715

If your data is really position: i then first repopulate a new HashMap in the form of {i, object}.

You can then put your hashmap entries inside a TreeMap, this will automaticly sort them. After you just iterate over the TreeMap and put the now sorted objects inside an array.

Example:

Map<Integer, Object> map = new TreeMap<>(yourMap);

Object[] sortedArray = new Object[map.size()];
int i = 0;
for(Map.Entry<Integer,Object> entry : map.entrySet()) {
  Object value = entry.getValue();
  sortedArray[i]=value;
  i++;
}

Upvotes: 0

Michael Laszlo
Michael Laszlo

Reputation: 12239

Sort the collection by position, then iterate over it and add each item to an ArrayList.

Upvotes: 3

Related Questions