AgentBawls
AgentBawls

Reputation: 109

Sort a list by an attribute within a sub list in java

I'm reading a delimited file into a custom object called "Holder". The Holder contains a List of custom objects called "Record". Each Record is alist of custom objects called "Field". Each Field has a String Name and String Value

public class Holder{
    private List RecordList;
    /* constructors and methods */
}

public class Record{
    private List FieldList
    /* constructors and methods */
}

public class Field{
    private String Name;
    private String Value;
    /* constructors and methods */
}

I'm pulling the Name for the Field object from a database based on the first item on the line. Here's a sample of the file I'm pulling in (line numbers - they'll also be Record indexes - starting at 0 added for ease of explanation):

0 - A,123
1 - B,123,123456
2 - B,123,654321
3 - B,123,112233
4 - C,123,choice1,1/1/2011,12/31/2011
5 - C,123,choice2,1/1/2011,12/31/2011
6 - D,123,choice1,1/1/2011,12/31/2011,654321
7 - D,123,choice1,1/1/2011,12/31/2011,112233

The Holder stores a list of Record objects. Each line becomes a Record object that stores a list of Field objects. Each string between commas becomes its own Value on a Field object. Ex: For the first "B" record (line 1), A Record BLine1 object will look like:

BLine1.getFieldList.get(0).getName() = "LineType"  //set from DAO not shown
BLine1.getFieldList.get(0).getValue() = "B"

BLine1.getFieldList.get(1).getName() = "Number"    //set from DAO not shown
BLine1.getFieldList.get(1).getValue() = "123"

BLine1.getFieldList.get(2).getName() = "Selection"  //set from DAO not shown
BLine1.getFieldList.get(2).getValue() = "123456"

I need to sort this list by every field. But depending on the LineType it is, the type and number of items to sort on changes. LineTypes can be added/taken away, and the fields can change. So I really need something as generic as possible.

It'll be ordered in the order the field is on the line. So it'll be sorted by FieldList.getValue(0), FieldList.getValue(1), .... FieldList.getValue(FieldList.size() - 1)

So, this is the order the line numbers should be in when it's done:

0
3   
1
2
4
5
7
6

What's the best/most efficient way of doing this sort?

Thanks in advance!

Upvotes: 0

Views: 561

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122424

Ignoring all possibility of nulls, how about this for a Comparator<Record>

public int compare(Record r1, Record r2) {
  // if one field list is longer than the other treat that one as greater
  int lenDiff = r1.getFieldList().size() - r2.getFieldList().size();
  if(lenDiff != 0) return lenDiff;

  // both field lists same length, do lexicographic comparison
  Iterator<Field> it1 = r1.getFieldList().iterator();
  Iterator<Field> it2 = r2.getFieldList().iterator();
  while(it1.hasNext()) {
    Field f1 = it1.next();
    Field f2 = it2.next();
    int diff = f1.getValue().compareTo(f2.getValue());
    if(diff != 0) return diff;
  }

  // all components equal, so both lists equal.
  return 0;
}

You could use this with Collections.sort.

Obviously if you might have a null record, or a record with a null field, or a field with a null value then it all gets rather more messy...

Upvotes: 1

Related Questions