Sorting a collection of objects
Implement the Comparator interface (once for each different sort order) and use the Collections.sort() method that takes a Comparator as additional parameter.
How to sort a Collection of Objects?
Collections.sort
Collections.sort(List<T> list)
sorts the specified list into ascending order, according to the natural ordering of its elements.
For example:
List<String> fruits = new ArrayList<String>();
fruits.add("Pineapple");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Banana");
Collections.sort(fruits);
int i=0;
for(String temp: fruits){
System.out.println("fruits " + ++i + " : " + temp);
}
Will give as output:
fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple
See other examples at: Java object sorting example (Comparable and Comparator).
Comparator
Comparator
is a comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort
or Arrays.sort
) to allow precise control over the sort order.
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getLastName().compareTo(o2.getLastName());
}
});
Lambda Expressions
Java 8 introduced Lambda Expressions and the Comparator
's equivalent is:
Comparator<Person> people =
(Person o1, Person o2)->o1.getLastName().compareTo(o2.getLastName());
How to sort a Collection of objects based on 2 properties
Use Java 8 methods of the Comparator
interface comparing()
and thenComparing()
:
Comparator<Transactions> byTypeAndTo =
Comparator.comparing(Transactions::getType)
.thenComparing(Transactions::getTo);
In order to sort a list of objects, you can apply method sort()
on it, available since Java 8:
transactions.sort(byTypeAndTo);
You can play around with this Online demo.
For more information on how to build comparators using Java 8, have a look at this tutorial.
But the last line of code gives an error:
The method signature is incorrect, I believe it should be:
public void processTransactions(Collection<Transactions> ts)
Don't confuse utility class Collections
with the Collection
interface, and don't omit the generic type parameter.
You can invoke method sort()
only on the object of type List
(the same with Collections.sort()
it expects a list and comparator).
In order to sort the list provided in the guise of Collection
you need to apply casting. Since you have a requirement that you method should expect an argument of type Collection
there's no other way around it (but it's not good design). That's how it might look like:
public void processTransactions(Collection<Transactions> ts) {
if (!(ts instanceof List<Transactions>)) {
throw new IllegalArgumentException();
}
List<Transactions> transactions = (List<Transactions>) tr;
transactions.sort(byTypeAndTo);
// process the `transactions` list
}
Note: it's better to define a comparator inside the Bank
class as a public static final
field.
Sort a Java collection object based on one field in it
here is my "1liner":
Collections.sort(agentDtoList, new Comparator<AgentSummaryDTO>(){
public int compare(AgentSummaryDTO o1, AgentSummaryDTO o2){
return o1.getCustomerCount() - o2.getCustomerCount();
}
});
UPDATE for Java 8:
For int datatype
Collections.sort(agentDtoList, (o1, o2) -> o1.getCustomerCount() - o2.getCustomerCount());
or even:
Collections.sort(agentDtoList, Comparator.comparing(AgentSummaryDTO::getCustomerCount));
For String datatype (as in comment)
Collections.sort(list, (o1, o2) -> (o1.getAgentName().compareTo(o2.getAgentName())));
..it expects getter AgentSummaryDTO.getCustomerCount()
Sorting object property by values
Move them to an array, sort that array, and then use that array for your purposes. Here's a solution:
let maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
let sortable = [];
for (var vehicle in maxSpeed) {
sortable.push([vehicle, maxSpeed[vehicle]]);
}
sortable.sort(function(a, b) {
return a[1] - b[1];
});
// [["bike", 60], ["motorbike", 200], ["car", 300],
// ["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]
Once you have the array, you could rebuild the object from the array in the order you like, thus achieving exactly what you set out to do. That would work in all the browsers I know of, but it would be dependent on an implementation quirk, and could break at any time. You should never make assumptions about the order of elements in a JavaScript object.
let objSorted = {}
sortable.forEach(function(item){
objSorted[item[0]]=item[1]
})
In ES8, you can use Object.entries()
to convert the object into an array:
const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
const sortable = Object.entries(maxSpeed)
.sort(([,a],[,b]) => a-b)
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
console.log(sortable);
How to natural-sort a collection of objects in JavaScript?
Ascending and Descending order
const arr = [{name: "John", size: "100"},{name: "John", size: "80"},{name: "John", size: "82"},{name: "John", size: "110"},{name: "John", size: "70"},{name: "John", size: "M"},{name: "John", size: "S"},{name: "John", size: "XS"},{name: "John", size: "L"},{name: "John", size: "XL"}],
handler = (a, b, desc) => {
if (isNaN(+a) && isNaN(+b)) return (desc ? b.localeCompare(a) : a.localeCompare(b));
else if (!isNaN(+a) && !isNaN(+b)) return (desc ? (+b - +a) : (+a - +b));
else if (isNaN(+a)) return (desc ? -1 : 1);
else return (desc ? 1 : -1);
},
descending = arr.sort(({size: a}, {size: b}) => handler(a, b, true)),
ascending = [...arr].sort(({size: a}, {size: b}) => handler(a, b));
console.log("Ascending")
console.log(ascending);
console.log("Descending")
console.log(descending);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Sorting a collection of objects in Java where implementing class is final
You can implement your own Comparator
without extending the class, and use it as a parameter for Collections.sort
:
public class MyComparator implements Comparator<MyClass> {
@Override
int compate (MyClass a, MyClass b) {
// null handling removed for clarity's sake
// add it if you need it
return a.getName().compareTo(b.getName());
}
}
And now just use it:
List<MyClass> myList = ...;
Collections.sort (myList, new MyComparator());
Java 8 - sort a Collection of Objects by a property with an order defined in an array
You can use Arrays.asList(names).indexOf(f.getName())
as comparison key:
List<String> nameList = Arrays.asList(names);
List<Foo> fooList = new ArrayList<>(fooCollection);
fooList.sort(Comparator.comparingInt(f -> nameList.indexOf(f.getName())));
Or if you definitely want Stream API:
List<Foo> fooList = fooCollection.stream()
.sorted(Comparator.comparingInt(f -> nameList.indexOf(f.getName())))
.collect(Collectors.toList());
However if you have many names, you may consider making this more efficient, preparing first a reverse index of names:
Map<String, Integer> nameMap = IntStream.range(0, names.length)
.boxed()
.collect(Collectors.toMap(idx -> names[idx], Function.identity()));
List<Foo> fooList = fooCollection.stream()
.sorted(Comparator.comparing(f -> nameMap.get(f.getName())))
.collect(Collectors.toList());
Here I assume that all the names are different and every Foo
has the corresponding name in the names
array.
Related Topics
Under What Conditions Is a Jsessionid Created
How to Use Try-With-Resources with Jdbc
Difference Between File.Separator and Slash in Paths
"Program to an Interface". What Does It Mean
Java and Gui - Where Do Actionlisteners Belong According to MVC Pattern
How to Switch Between Frames in Selenium Webdriver Using Java
Java Securityexception: Signer Information Does Not Match
Java.Lang.Unsupportedclassversionerror: Bad Version Number in .Class File
Output in a Table Format in Java's System.Out
Why Do We Use Autoboxing and Unboxing in Java
Convert Java.Util.Date to Java.Time.Localdate
Java Maximum Memory on Windows Xp
How to Find Files That Match a Wildcard String in Java
Java.Lang.Classnotfoundexception: Com.Mysql.Jdbc.Driver in Eclipse
Why Does the Division of Two Integers Return 0.0 in Java
Regex to Match a C-Style Multiline Comment