Reputation: 461
I am new to the idea of comparators and I am looking into ways to sort strings. In my code, below, I have made a list and sorted through it using the Collections.sort()
method. Here is the code:
public class ComparatorTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
List<String> list = new ArrayList<String>();
list.addAll(Arrays.asList("Bob Stone", "Jordan Brand", "Bob Mass", "Dylan Walsh","Tom Mavis","Bob Ganley"));
System.out.println("Before sort "+ list);
Collections.sort(list);
System.out.println("After sort "+ list);
}
}
How can I modify this to sort using a given String to sort by, instead of just sorting alphabetically? For example, if I give the string BOB
then all the BOB's will move to the front of the list. I did ask a sorting question before but I misunderstood the idea of sorting and it was more of a filtering question (java sort list of strings by string value entered by a user). This question is different from my earlier question because now I am trying to actually sort and rearrange the Strings instead of filtering them.
Upvotes: 1
Views: 1101
Reputation: 347204
The first thing you need to do is understand the rules, for example, what happens when:
A simple implementation might look something like...
public class NameComparator implements Comparator<String> {
private String name;
public NameComparator(String name) {
this.name = name;
}
@Override
public int compare(String lhs, String rhs) {
if (lhs.startsWith(name) && rhs.startsWith(name)) {
return lhs.compareTo(rhs);
} else if (lhs.startsWith(name)) {
return -1;
} else if (lhs.startsWith(name)) {
return 1;
}
return lhs.compareTo(rhs);
}
}
Now, this does a case match (so bob
is not the same as Bob
) and will sub-sort all the "Bobs" within their own group
As you see, five seconds of thinking has brought up a lot of possible ways to sort the list, so you need to be aware of your options, which ones you might want to be customisable and which ones you want to be fixed.
You can call this example using something like...
Collections.sort(list, new NameComparator("Bob"));
Which will, based on your available input, output...
Before sort [Bob Stone, Jordan Brand, Bob Mass, Dylan Walsh, Tom Mavis, Bob Ganley]
After sort [Bob Ganley, Bob Mass, Bob Stone, Dylan Walsh, Jordan Brand, Tom Mavis]
Upvotes: 2
Reputation: 338664
Collator
classThe rules used in comparing and sorting natural language (human language) are formally referred to as collation.
In Java, the rules of any collation are defined in a class implementing Collator
class. Usually, its subclass RulesBasedCollator
is used for comparing/sorting. The CollatorProvider
class is an SPI (service provider interface) for providing a registered Collator
implementation. Recent versions of Java default to collation definitions provided by the Unicode Consortium in their Common Locale Data Repository (CLDR).
Presumably, you are free to build your own Collator
implementation with such special rules as you desire.
Be aware that collation is a very complicated field, with rules widely varying by human language and by cultural norms. If you are only concerned with American English, you may have few issues. But if you deal with other languages, cultures, or alternate characters such as ©
or emoji, well, here be dragons.
Upvotes: 2
Reputation: 140326
You can use the Boolean.compare
method to check if the strings begin with "Bob":
Comparator<String> bobsFirst = (a, b) -> Boolean.compare(b.startsWith("Bob"), a.startsWith("Bob"));
Comparing them this way around (b first, then a) puts things starting with "Bob" first.
Then, tie break using natural ordering:
Comparator<String> comparator = bobsFirst.thenComparing(a -> a);
Note that startsWith
is case sensitive. To ignore the case of "Bob", you could replace b.startsWith("Bob")
(similarly for a
) with:
b.regionMatches(true, 0, "Bob", 0, 3)
Upvotes: 4