2017-09-14 6 views
2

J'ai une liste de objects que je veux trier sur la base de name. J'ai fait le codage où il est trié sur la base de name mais j'ai une exigence légèrement différente.Java: Trier une liste d'objets en utilisant le comparateur avec le deuxième mot de la propriété

Les noms sont pour l'exemple que j'ai actuellement triés en utilisant le code ci-dessous:

Bull AMP 
Cat DEF 
Dog AMP 
Frog STR 
Zebra DEF 

Mais je veux le nom trié sur la base du deuxième mot dans le nom. Fondamentalement, le list devrait être quelque chose comme ceci:

Bull AMP 
Dog AMP 
Cat DEF 
Zebra DEF 
Frog STR 

Ci-dessous mon code:

classe de l'objet:

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; 
} 

classe Comparator

public class AnimalDataComparer implements Comparator<AnimalData> 
     { 
    @Override 
    public int compare(final AnimalData object1, final AnimalData object2) 
    { 
      return object1.getName().compareTo(object2.getName()); 
    } 
    } 

tri à l'aide de collections

private List<AnimalData> AnimalDataList; 

    Collections.sort(AnimalDataList, AnimalDataComparer); 
+0

Votre méthode equals doit aussi représenter ce comportement. –

+1

ce qui est AMP, DEF etc. pour un champ ?? –

+0

ou sont ces suffixes partie du champ Nom de la chaîne? –

Répondre

1

En mode Java 8 Streams:

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()); 
+0

Ce code Java 8 n'est pas" complet "- il duplique la logique du comparateur pour les deux arguments. –

+0

Eh bien, il y a deux variables différentes à comparer car il utilise la classe StringTokenizer – nineunderground

3

Vous devez mettre en œuvre vous-même, comme suit, en supposant que le mot fait partie de name, avec substring() et 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(" ") 
    )); 
} 

Si pour une raison quelconque, vous avez plus de deux mots et le dernier est celui que vous voulez, puis utilisez lastIndexOf()

4

Changer votre Comparator comme ceci:

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]); 
    } 
} 

ou utiliser les plus récentes de l'API Java Comparator:

Comparator<AnimalData> c = Comparator.comparing(animal -> animal.getName().split(" ")[1]); 

Notez que ceci suppose que tous les noms ont en fait deux mots. Si vous ne le savez pas, vous devez vérifier avant d'accéder à la matrice scindée. En dehors de tout cela, vous pouvez penser aux autres commentaires et diviser le nom dans votre constructeur et avoir deux champs, name et category. Ou vous pouvez écrire un getter pour la catégorie, dans lequel vous faites le fractionnement et la validation.

0

Ici, il est

SORTIE ::

[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 + "]"; 
    }