Reputation: 4424
I have a list of objects
which i want to sort on basis of name
. I have done coding where it does get sorted on basis of name
but i have a slight different requirement.
The names are for Example which i have currently sorted using the below code:
Bull AMP
Cat DEF
Dog AMP
Frog STR
Zebra DEF
But i want the name sorted on the basis of second word in the name. Basically the list
should be something like this:
Bull AMP
Dog AMP
Cat DEF
Zebra DEF
Frog STR
Below is my code:
Object Class:
public class AnimalData implements Serializable
{
private static final long serialVersionUID = 3952396152688462601L;
public String name;
public long age;
private String animal;
private String animalParts;
private String animalType;
}
Comparator Class
public class AnimalDataComparer implements Comparator<AnimalData>
{
@Override
public int compare(final AnimalData object1, final AnimalData object2)
{
return object1.getName().compareTo(object2.getName());
}
}
Sorting using Collections
private List<AnimalData> AnimalDataList;
Collections.sort(AnimalDataList, AnimalDataComparer);
Upvotes: 3
Views: 2585
Reputation: 90
In Java 8 Streams mode:
Comparator<? super Animal> animalComparator = (a, b) -> {
StringTokenizer firstTokenizer = new StringTokenizer(a.getName(), " ");
firstTokenizer.nextToken();
StringTokenizer secondTokenizer = new StringTokenizer(b.getName(), " ");
secondTokenizer.nextToken();
return firstTokenizer.nextToken().compareTo(secondTokenizer.nextToken());
};
myList = myList.stream().sorted(animalComparator).collect(Collectors.toList());
Upvotes: 1
Reputation: 11759
You need to implement this yourself, as follows, assuming that the word is part of name
, with substring()
and indexOf()
:
@Override
public int compare(final AnimalData object1, final AnimalData object2)
{
return object1.getName().substring(
object1.getName().indexOf(" ")
).compareTo(object2.getName().substring(
object2.getName().indexOf(" ")
));
}
If for some reason you have more than two words and the last is the one you want, then use lastIndexOf()
Upvotes: 3
Reputation: 645
Here it is
OUTPUT::
[AnimalData [name=Dog AMP], AnimalData [name=Cat DEF], AnimalData [name=Zebra DEF], AnimalData [name=Frog STR]]
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class test {
public static void main(String[] args) throws IOException, ParseException {
AnimalData data1 = new AnimalData("Cat DEF");
AnimalData data2 = new AnimalData("Dog AMP");
AnimalData data3 = new AnimalData("Frog STR");
AnimalData data4 = new AnimalData("Zebra DEF");
List<AnimalData> list = new ArrayList<>();
list.add(data1);
list.add(data2);
list.add(data3);
list.add(data4);
Collections.sort(list);
System.out.println(list);
}
}
class AnimalData implements Serializable, Comparable<AnimalData> {
private static final long serialVersionUID = 3952396152688462601L;
public String name;
public long age;
private String animal;
private String animalParts;
private String animalType;
public AnimalData(String name) {
super();
this.name = name;
}
@Override
public int compareTo(AnimalData o) {
String secondPartThis = this.name.split(" ")[1];
String secondPartObject = o.name.split(" ")[1];
return secondPartThis.compareTo(secondPartObject);
}
@Override
public String toString() {
return "AnimalData [name=" + name + "]";
}
Upvotes: 0
Reputation: 4555
Change your Comparator like this:
public class AnimalDataComparer implements Comparator<AnimalData>
{
@Override
public int compare(final AnimalData object1, final AnimalData object2)
{
return object1.getName().split(" ")[1].compareTo(object2.getName().split(" ")[1]);
}
}
or use Java's newer Comparator API:
Comparator<AnimalData> c = Comparator.comparing(animal -> animal.getName().split(" ")[1]);
Note that this is assuming that all names actually have two words. If you do not know that for sure, you need to check before accessing the split array.
Aside from all that, you might want to think about the other comments and split the name in your constructor and have two fields, name
and category
. Or you could write a getter for category, in which you do the splitting and validation.
Upvotes: 4