2017-06-26 1 views
1

J'ai une situation où j'ai besoin de faire une liste d'objet, où l'objet a (élément, titre) élément. par exemple :Comment donner Rank dans la liste d'objets et trier sur la base de Rank et de toute autre clé?

obj1 = ('john', 'colonel') 
obj2 = ('Alex', 'major') 
obj3 = ('Roy', 'Major general') 
obj4 = ('derrick', 'no Rank') 

que je dois faire le tri de deux façons: 1. Tout d'abord sur la base Titre. 2. Pour deux noms quelconques, si le titre est le même que le tri de l'objet sur la base du nom alphabétique (comme l'ordre chronologique du nom). 3. Et aussi besoin de supprimer les noms en double de la liste.

S'il vous plaît aidez-moi comme je sais comment trier l'arraylist mais je ne sais pas comment donner le classement et trier sur de multiples conditions. Si vous avez besoin de plus de détails ou si vous ne comprenez pas ma question, merci de me le faire savoir.

+0

envisager d'utiliser un ENUM –

+0

* Comment * souhaitez-vous trier sur le titre? Alphabétiquement? – shmosel

+0

Que voulez-vous supprimer en cas de doublons? – shmosel

Répondre

0

Vous devez créer une classe Comparator, quelque chose comme ceci:

class ObjectComparator implements Comparator<SomeClass>{ 

    @Override 
    public int compare(SomeClass obj1, SomeClass obj2) { 
     // if two objects' ranks are the same 
     if(obj1.rank.equals(obj2.rank)){ 
      // then compare their names 
      return obj1.name.compareTo(obj2.name); 
     } 
     else{ 
      return obj1.rank.compareTo(obj2.rank); 
     } 
    } 
} 

Je ne comprends pas comment vous voulez supprimer les doublons de l'attribut name parce que cela va ruiner le tri, à moins que vous voulez dire à supprimer les doublons de même name et rank (par exemple obj1 = "john" "colonel" et aussi obj2 ="john" "colonel") puis dans ce cas, utilisez un Set après carrément les méthodes remplaçant equal et hashCode dans votre classe, de sorte que votre jeu peut savoir si les deux objets sont égaux ... quelque chose comme ceci:

@Override 
@Override 
public boolean equals(Object other){ 
    if(other==null) return false; 
    if (other == this) return true; 
    return ((SomeClass)other).name.equalsIgnoreCase(this.name) 
      && ((SomeClass)other).rank.equalsIgnoreCase(this.rank); 
} 

@Override 
public int hashCode() { 
    return Objects.hash(name, rank); 
} 

Mais si vous voulez dire que vous voulez supprimer les doublons name s (à savoir les objets ont les mêmes champs mais des rangs différents), alors vous pouvez envisager d'utiliser un LinkedHashMap qui préserve l'ordre des éléments, mais comme je l'ai mentionné, ce sera pas préserver l'ordre de tri pour la copie particulière (TBH Je ne pense pas que ce que vous vouliez dire par doublons) ...un exemple pour les tests:

public class SomeClass{ 
    String name, rank; 

    public SomeClass(String name, String rank){ 
     this.name = name; 
     this.rank = rank; 
    } 
    public static void main(String[] args) { 
     SomeClass obj1 = new SomeClass("john", "colonel"); 
     SomeClass obj2 = new SomeClass("XXX", "major"); 
     SomeClass obj3 = new SomeClass("Roy", "general"); 
     SomeClass obj4 = new SomeClass("derrick", "no Rank"); 
     SomeClass obj5 = new SomeClass("john", "something"); 
     SomeClass obj6 = new SomeClass("Alex", "major"); 
     List<SomeClass> list = new ArrayList<>(); 
     list.add(obj1); list.add(obj2); list.add(obj3); 
     list.add(obj4); list.add(obj5); list.add(obj6); 

     System.out.println(getSortedObjects(list)); 

    } 

    public static Map<String, List<String>> getSortedObjects(List<SomeClass> list){ 
     Map<String, List<String>> sortedMap = new LinkedHashMap<>(); 
     // sort the list 
     Collections.sort(list, new ObjectComparator()); 

     for(SomeClass obj : list){ 
      // for testing sorting before ruining it in a map 
      System.out.println(obj.name + " " + obj.rank); 

      List<String> temp; 
      if(sortedMap.containsKey(obj.name)){ 
       temp = sortedMap.get(obj.name); 
       temp.add(obj.rank); 
       sortedMap.put(obj.name, temp); 
      } 
      else{ 
       temp = new ArrayList<>(); 
       temp.add(obj.rank); 
       sortedMap.put(obj.name, temp); 
      } 
     } 

     return sortedMap; 
    } 
} 

test

john colonel 
Roy general 
Alex major 
XXX major 
derrick no Rank 
john something 
{john=[colonel, something], Roy=[general], Alex=[major], XXX=[major], derrick=[no Rank]} 

Exemple de mise en œuvre complète de Set & Comparator:

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.LinkedHashSet; 
import java.util.List; 
import java.util.Objects; 
import java.util.Set; 

public class SomeClass{ 
    // suppose the fields in your class 
    String name, rank; 

    // simple constructor 
    public SomeClass(String name, String rank){ 
     this.name = name; 
     this.rank = rank; 
    } 


    // you need to override both equals and hashCode methods from 
    // Object superclass in order the set works properly and realizes 
    // that two given objects of type SomeClass are equal 
    @Override 
    public boolean equals(Object other){ 
     if(other==null) return false; 
     if (other == this) return true; 
     return ((SomeClass)other).name.equalsIgnoreCase(this.name) 
       && ((SomeClass)other).rank.equalsIgnoreCase(this.rank); 
    } 


    @Override 
    public int hashCode() { 
     return Objects.hash(name, rank); 
    } 


    @Override 
    public String toString(){ 
     return name + " " + rank; 
    } 

    /** 
    * Pass a set then add the items to a temporary ArrayList 
    * to be sorted according to the Comparator condition 
    * then clear the set and add the sorted element back 
    * @param list 
    */ 
    public static void sort(Set<SomeClass> list){ 
     List<SomeClass> temp = new ArrayList<>(); 
     temp.addAll(list); 
     // anonymous class implementation of Comparator 
     Collections.sort(temp, new Comparator<SomeClass>(){ 

       @Override 
       public int compare(SomeClass obj1, SomeClass obj2) { 
        // if two objects' ranks are the same 
        if(obj1.rank.equals(obj2.rank)){ 
         // then compare their names 
         return obj1.name.compareTo(obj2.name); 
        } 
        else{ 
         return obj1.rank.compareTo(obj2.rank); 
        } 
       }}); 

     list.clear(); 
     list.addAll(temp); 
    } 


    // testing 
    public static void main(String[] args) { 
     // create Objects of the class with duplicate 
     SomeClass obj1 = new SomeClass("john", "colonel"); 
     SomeClass obj2 = new SomeClass("XXX", "major"); 
     SomeClass obj3 = new SomeClass("Roy", "general"); 
     SomeClass obj4 = new SomeClass("derrick", "no Rank"); 
     SomeClass obj5 = new SomeClass("john", "something"); 
     SomeClass obj6 = new SomeClass("Alex", "major"); 
     SomeClass obj7 = new SomeClass("Alex", "major"); // duplicate object 


     // LinkedHashSet PRESERVES the order of elements' insertion 
     // in addition to removing duplicates 
     Set<SomeClass> list = new LinkedHashSet<>(); 

     // populate the set 
     list.add(obj1); list.add(obj2); list.add(obj3); 
     list.add(obj4); list.add(obj5); list.add(obj6); 
     list.add(obj7); 

     //before sorting 
     System.out.println("Before " + list); 

     // after sorting 
     sort(list); 
     System.out.println("After " + list); 

    } 
} 

Test:

Before [john colonel, XXX major, Roy general, derrick no Rank, john something, Alex major] 
After [john colonel, Roy general, Alex major, XXX major, derrick no Rank, john something] 
+0

Merci Yaha et Ryan, pour vos commentaires. Cela résout mon problème. – karam

+0

Merci yaha pour vos efforts précieux, Oui, je confirme que je ne vais pas obtenir des enregistrements en double et pas besoin de supprimer les doublons. Une autre chose que j'ai besoin d'ajouter après avoir obtenu des informations sur la méthode de comparaison est qu'après le tri, je n'obtenais toujours pas l'ordre alphabétique correct pour le même rang. J'appliquais en fait deux niveaux de tri en fonction du rang puis si le même titre pour deux noms, le nom devrait apparaître dans l'ordre alphabétique sans perturber l'ordre de Rank. Vous me donnez le bon pointeur et je l'implémente. Je partagerai mon code dès que j'aurai accès. – karam

0

Vous devez lire des comparateurs et en implémenter un pour votre classe.

Si vous utilisez Java 8, le plus simple est d'utiliser Comparators.comparing

https://praveer09.github.io/technology/2016/06/21/writing-comparators-the-java8-way/

Afin d'éviter les doublons de noms, je garderais un ensemble distinct (qui limite automatiquement l'unicité) des noms qui existent déjà. Vérifiez que cet ensemble contient les noms avant d'ajouter le nouvel objet à l'arborescence.