简体   繁体   中英

Sorting huge Array List (ArrayList<Class>) based on values of class members in Java

There are two sub-problems.

1- Comparing two huge arraylists

2- Sorting elements of arraylist based on the values of its object to achieve (1).

I have an ArrayList of objects of a class. ie

Class X
{
    double x;
    double y;
    int sortVal;
}

ArrayList<X> alX = new ArrayList<X>(); //size = 10,000
ArrayList<Integer> myValue = new ArrayList<Integer>(); //size = 15

I want to check if myValue is present in sortVal.

X ob = new X();
for(i=0;i<myValue.size();i++)
{
   for(j=0;j<alX.size();j++)
   {  
      ob = alX.get(j)
      **if (myValues.get(i) == ob.sortVal)**
   }
}

As the size of the arraylist 'alX' is huge, it takes high computation time.

I thought the better way would be to sort the elemets of ArrayList alX based on the values of sortVal of Class X. By sorting, once sortVal is greater than myValue, I can break from the loop.

1) how can I sort the elements of arraylist alX based on the value 'sortVal'.

2) Is there a better approach, than sorting the arraylist, to compare the two values. ie (myValues.get(i) == alX.ob.sortVal)

[edit] Consider the values being,

ArrayList<X>:
x      : 1,1,1,2,3,5,4,5
y      : 2,4,6,4,4,6,2,1
sortVal: 10,20,30,10,10,20,30

ArrayList<Integer>:
myValue: 10,20,30

You could construct a Map<Integer, X> if sortVal values are unique or Map<Integer, Lists<X>> if they are not. This has a time complexity of O(n) instead or O(n * log n) which is the cost of doing a sort.


EDIT: This builds a MultiMap of keys and the set of objects for that key in one pass.

List<X> xs = ...
Map<Integer, Set<X>> mapBySortVal = new LinkedHashMap<>();
for(X x: xs) {
   Set<X> set = mapBySortVal.get(x.sortVal);
   if (set == null)
      mapBySortVal.put(x.sortVal, set = new LinkedHashSet<>());
   set.add(x);
}

for(Integer value: myValues) {
   Set<X> xs = mapBySortVal.get(value);
   if (xs != null) 
       // found some.
}

For your first question, you can sort a collection on anything you can think of by specifying the Comparator it should use (see Collections#sort )

Since you named your field sortVal , I would guess instances of this class can be sorted based on that value and you might want to implement the Comparable interface for that class. That way, you can use Collections#sort without having to specify the Comparator

Google guava get very useful functions. For ordering of arrays it provide com.google.common.collect.Ordering<T> .

For example:

Ordering<String> byLengthOrdering = new Ordering<String>() {
 public int compare(String left, String right) {
   return Ints.compare(left.length(), right.length());
 }
};
List<String> sorted = byLengthOrdering.reverse().sortedCopy(sourceList);

Depending on your requirement there are 2 approaches: Use Map, which orders its elements by natural order by default. But will take more memory.

OR

Sort using comparator. Will take more time.

Just look at their docs for explanation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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