How to Sort by Two Fields in Java and Specify Sort Direction

How to sort by two fields in Java and specify sort direction?

As simple as adding a reversed...

list.sort(Comparator.comparing(ClassA::getVar1)
.thenComparing(Comparator.comparing(ClassA::getVar2).reversed()));

How to sort by two fields in Java?

You can use Collections.sort as follows:

private static void order(List<Person> persons) {

Collections.sort(persons, new Comparator() {

public int compare(Object o1, Object o2) {

String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);

if (sComp != 0) {
return sComp;
}

Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}});
}

List<Persons> is now sorted by name, then by age.

String.compareTo "Compares two strings lexicographically" - from the docs.

Collections.sort is a static method in the native Collections library. It does the actual sorting, you just need to provide a Comparator which defines how two elements in your list should be compared: this is achieved by providing your own implementation of the compare method.

Java 8 Sort using 2 fields

You can use group comparator and parallel stream as follows:

List<Document> outList = documentList.stream()
.filter(....)
.sorted(Comparator.comparing(Document::getPdate)
.thenComparing(Document::getSubject))
.parallel();

Collections.sort with multiple fields

Do you see anything wrong with the code?

Yes. Why are you adding the three fields together before you compare them?

I would probably do something like this: (assuming the fields are in the order you wish to sort them in)

@Override public int compare(final Report record1, final Report record2) {
int c;
c = record1.getReportKey().compareTo(record2.getReportKey());
if (c == 0)
c = record1.getStudentNumber().compareTo(record2.getStudentNumber());
if (c == 0)
c = record1.getSchool().compareTo(record2.getSchool());
return c;
}

Most efficient way to sort by multiple fields in Java

The key thing to realize here is that your search algorithm always stays exactly the same. The only thing that changes is your actual comparison function.

I would recommend using a standard sort in the Arrays or Collections class, but writing your own custom Comparable class or Comparator, whose compare method will use the data the user supplies. This is actually kind of interesting - I've only ever written Comparable classes that use fixed data, but this is exactly a use case for them.

All you need to do is write the function

public int compare(Row row1, Row row2) {
// iterate over the columns *in order of the user-supplied priority*
// return appropriately
}

Here's documentation on the Comparable class.

And Comparator.

Which one you need depends on what you're implementing, I forget the details but should be straightforward.

The key #2 thing here is that you can instantiate your ColumnPrioritiesComparable class before the priorities are set. e.g.

class ColPriComp implements Comparable<ColPriComp> {
private volatile int[] priorities; // possibly static, or obtained some other way,
// so there's only one shared among all classes

@Override
public int compareTo(ColPriComp other) {
// use "priorities" to do the comparison
}

public void setPriorities(int[] newPriorities) {
this.priorities = newPriorities;
}
}

Java stream sort by 2 fields

I have found best possible way to do it, since i'm using Kotlin it can be done like this:

result.sortedWith(compareBy({ it.intervalType.orderIndex }, { it.item.amount }))

How to sort an arraylist by 2 fields?

        List<YourClass> list = new ArrayList<>();

The following works like this.

  • Comparator.comparing(YourClass::getLength).reversed() sorts on the length field in desending order.
  • if the above results in equal lengths, then .thenComparing(YourClass::getPosition) sorts on the position in lexical order.
        list.sort(Comparator.comparing(YourClass::getLength).reversed()
.thenComparing(YourClass::getPosition));
// or with no getters

list.sort(Comparator.comparing((YourClass cl) -> cl.length).reversed()
.thenComparing((YourClass cl) -> cl.position));

A possible structure of your coordinate class.

class YourClass {
int length;
public String position;
int coordX;
int coordY;

public int getLength() {
return length;
}

public String getPosition() {
return position;
}

public int getCoordX() {
return coordX;
}

public int getCoordY() {
return coordY;
}
}

Spring Data Rest - Sort by multiple properties

Solution (tl;dr)

When wanting to sort on multiple fields you simply put the sort parameter multiple times in the URI. For example your/uri?sort=name,asc&sort=numberOfHands,desc. Spring Data is then capable of constructing a Pageable object with multiple sorts.

Explanation

There is not really a defined standard on how to submit multiple values for a parameter in a URI. See Correct way to pass multiple values for same parameter name in GET request.

However there is some information in the Java Servlet Spec which hints on how Java servlet containers parse request parameters.

The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. ... - Java Servlet Spec, section 3.1

The sample further in that section states (although it mixes request and body data)

For example, if a request is made with a query string of a=hello and a post body of a=goodbye&a=world, the resulting parameter set would be ordered a=hello, goodbye, world.

This sample shows that when a parameter (a in the example) is presented multiple times the results will be aggregated into a String[].

Sort a List of objects by multiple fields

Your Comparator would look like this:

public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
public int compare(GraduationCeremony o1, GraduationCeremony o2) {
int value1 = o1.campus.compareTo(o2.campus);
if (value1 == 0) {
int value2 = o1.faculty.compareTo(o2.faculty);
if (value2 == 0) {
return o1.building.compareTo(o2.building);
} else {
return value2;
}
}
return value1;
}
}

Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).



Related Topics



Leave a reply



Submit