简体   繁体   中英

Java: how to sort and group a list of objects by their attributes

For Example I have a java object called RecordGroup. class signature is give below:

public class RecordGroup {

private String owner;
private Integer startRow;
private Integer recordCount;

public RecordGroup() {
}

public RecordGroup(String owner, Integer startRow, Integer recordCount) {
    this.owner = owner;
    this.startRow = startRow;
    this.recordCount = recordCount;
}

public String getOwner() {
    return owner;
}

public void setOwner(String owner) {
    this.owner = owner;
}

public Integer getRecordCount() {
    return recordCount;
}

public void setRecordCount(Integer recordCount) {
    this.recordCount = recordCount;
}

public Integer getStartRow() {
    return startRow;
}

public void setStartRow(Integer startRow) {
    this.startRow = startRow;
}

}

And, i have a List which holds a list of above object as given below.

public class Test {

List<'RecordGroup'> mergerMap = new ArrayList<'RecordGroup'>();

    mergerMap.add(new RecordGroup("RECORD", 1, 6));
    mergerMap.add(new RecordGroup("RECORD", 7, 9));
    mergerMap.add(new RecordGroup("RECORD", 3, 4));
    mergerMap.add(new RecordGroup("ZONE", 3, 1));
    mergerMap.add(new RecordGroup("MODULE", 5, 6));
    mergerMap.add(new RecordGroup("ZONE", 14, 28));
    mergerMap.add(new RecordGroup("ZONE", 6, 30));
    mergerMap.add(new RecordGroup("MODULE", 1, 60));
    mergerMap.add(new RecordGroup("OFFICE", 2, 4));
    mergerMap.add(new RecordGroup("OFFICE", 8, 6));
    mergerMap.add(new RecordGroup("USER", 1, 6));
    mergerMap.add(new RecordGroup("USER", 9, 8));
    mergerMap.add(new RecordGroup("USER", 5, 7));
    mergerMap.add(new RecordGroup("OFFICE", 3, 1));

}

My Question is, how to sort the above List of RecordGroup objects by their 'owner' and 'startRow' so that it can group the records by owner ie first "ZONE" group and then "OFFICE" group and then "USER" group and then "MODULE" and finally "RECORD" group should appear in the list. It should also consider the "startRow" field while sorting and grouping ie arrange each group by value of the "startRow" field in ascending order.

Out put should be like this:

mergerMap.add(new RecordGroup("ZONE", 3, 1));
mergerMap.add(new RecordGroup("ZONE", 6, 30));
mergerMap.add(new RecordGroup("ZONE", 14, 28));
mergerMap.add(new RecordGroup("OFFICE", 2, 4));
mergerMap.add(new RecordGroup("OFFICE", 3, 1));
mergerMap.add(new RecordGroup("OFFICE", 8, 6));
mergerMap.add(new RecordGroup("USER", 1, 6));
mergerMap.add(new RecordGroup("USER", 5, 7));
mergerMap.add(new RecordGroup("USER", 9, 8));
mergerMap.add(new RecordGroup("MODULE", 1, 60));
mergerMap.add(new RecordGroup("OFFICE", 2, 4));
mergerMap.add(new RecordGroup("MODULE", 5, 6));
mergerMap.add(new RecordGroup("RECORD", 1, 6));
mergerMap.add(new RecordGroup("RECORD", 3, 4));
mergerMap.add(new RecordGroup("RECORD", 7, 9));

you have to write your own comparator, so that it does what you want with the object of your specific and specialized collection..

try to give a look here Interface Comparator

EDIT: probably comparable is even better as the other answer suggests

Simple implement the Comparable Interface of Java, override the compareTo function as required and push your RecordGroups to a SortedSet, like TreeSet or sth.

http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html

http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html

Update: If you need different sortings for different Locations, a Entity-bound compare function would ofc. not be what you want to implement. (It will be equal through the whole system). If this is the Case, just use a Comperator per sorting case.

You should probably implement the java.lang.Comparable interface:

public class RecordGroup implements Comparable<RecordGroup> {
  //Rest of your implementation
  @Override
  public int compareTo(RecordGroup o) {
     //logic to compare two RecordGroup objects
  }
}

Comparator does this for you Comparator

use following code.

public int compare(RecordGroup o1, RecordGroup o2) {
if (o1.getOwner().compareTo(o2.getOwner()) == 0) {
return o1.getStartRow() - o2.getStartRow();
} else {
return o1.getOwner().compareTo(o2.getOwner());
}
}
});

to check working demo go to http://ideone.com/rsM9Un for demo Here startRow is in ascending Order

Output :

[MODULE , 1
, MODULE , 5
, OFFICE , 2
, OFFICE , 3
, OFFICE , 8
, RECORD , 1
, RECORD , 3
, RECORD , 7
, USER , 1
, USER , 5
, USER , 9
, ZONE , 3
, ZONE , 6
, ZONE , 14
]

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