Reputation: 2343
Working with a list of Object
where one of the item has an empty String
. Trying to write method which would return a sorted list. By sorting means the first item value of the list should always be an empty String
.
Since I don't want to manipulate the unsorted list, I am creating a new list to sort.
So far my code is:
private List<LoggerConfig> sort(List<LoggerConfig> unSortedList) {
List<LoggerConfig> sortedList = new ArrayList<LoggerConfig>(unSortedList);
//What to do here
return sortedList;
}
Looked at lot of SO
posts but very confused.
Upvotes: 0
Views: 757
Reputation: 14572
You can trust the String.compareTo
to match the order you seek. Here is a Comparator :
new Comparator<LoggerConfig>() {
@Override
public int compare(LoggerConfig o1, LoggerConfig o2) {
return (o1.getName().compareTo(o2.getName()));
}
};
or directly implementing Comparable
in the specific class (here Dummy)
class Dummy implements Comparable<Dummy>{
String name;
public int compareTo(Dummy o) {
return this.name.compareTo(o.name);
}
}
The why :
The String.compareTo
check the first characters of both to find a difference (until the smallest length of both), if they match, the lengths are use to make the difference, the longest will be after the shortest (shortest.compareTo(longuest)
will return an negative value (the length difference)).
In this case, "".compareTo("abc")
, there is no character in the empty String, so the first check is skipped and the length is use to compare the String
s, so an empty String
will always be seen as first compare to any "non-empty" String
An example with the previous Dummy
class (just need to add the Constructor Dummy(String)
:
public class Main {
public static void main(String[] args) {
List<Dummy> dummies = new LinkedList<Dummy>();
dummies.add(new Dummy("abc.com.core"));
dummies.add(new Dummy(""));
dummies.add(new Dummy("abc.com.core.def"));
System.out.println("BEFORE : " + dummies);
Collections.sort(dummies);
System.out.println("AFTER : " + dummies);
}
}
Output :
BEFORE : [abc.com.core, , abc.com.core.def]
AFTER : [, abc.com.core, abc.com.core.def]
Upvotes: 2
Reputation: 5926
The Comparator
solution seems feasible to me; what you're missing is implementing the compare
method so that it does what you want.
Collections.sort(sortedList, new Comparator<LoggerConfig>() {
@Override
public int compare(LoggerConfig o1, LoggerConfig o2) {
if(o1.getName().equals("")){
return -1;
} else if(o2.getName().equals("")) {
return 1;
} else {
return (o1.getName().compareTo(o2.getName()));
}
}
});
As per Java docs, the Comparator
has a compare
method that returns an int which is
So the Comparator
you need should return the comparison of the two strings if they're both different from ""
, and -1 (or 1) if the first (or second) String is empty.
Upvotes: 1
Reputation: 11942
You can place this condition in your comparator so that elements with an empty value are considered "less" than other elements, so that it shows up at the beginning of the sorted list. Try something like this:
Collections.sort(sortedList, new Comparator<LoggerConfig>() {
@Override
public int compare(LoggerConfig o1, LoggerConfig o2) {
if(o1.getName().isEmpty(){
return -1;
}
if(o2.getName().isEmpty(){
return 1;
}
return (o1.getName().compareTo(o2.getName()));
}
});
I didn't test this, but this should make the idea clear. If the empty element shows up at the end of the list, swap the -1
and the 1
.
If your List is huge and sorting takes a lot of time, it might be a better idea to remove the empty element before sorting, then sort, then place the element at the beginning.
Upvotes: 1