Comment utiliser Comparator en Java pour trier

169

J'ai appris à utiliser le comparable mais j'ai des difficultés avec le comparateur. J'ai une erreur dans mon code:

Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable
 at java.util.Arrays.mergeSort(Unknown Source)
 at java.util.Arrays.sort(Unknown Source)
 at java.util.Collections.sort(Unknown Source)
 at New.TestPeople.main(TestPeople.java:18)

Voici mon code:

import java.util.Comparator;

public class People implements Comparator {
   private int id;
   private String info;
   private double price;

   public People(int newid, String newinfo, double newprice) {
       setid(newid);
       setinfo(newinfo);
       setprice(newprice);
   }

   public int getid() {
       return id;
   }

   public void setid(int id) {
       this.id = id;
   }

   public String getinfo() {
       return info;
   }

   public void setinfo(String info) {
       this.info = info;
   }

   public double getprice() {
       return price;
   }

   public void setprice(double price) {
       this.price = price;
   }

   public int compare(Object obj1, Object obj2) {
       Integer p1 = ((People) obj1).getid();
       Integer p2 = ((People) obj2).getid();

       if (p1 > p2) {
           return 1;
       } else if (p1 < p2){
           return -1;
       } else {
           return 0;
       }
    }
}
import java.util.ArrayList;
import java.util.Collections;

public class TestPeople {
    public static void main(String[] args) {
        ArrayList peps = new ArrayList();

        peps.add(new People(123, "M", 14.25));
        peps.add(new People(234, "M", 6.21));
        peps.add(new People(362, "F", 9.23));
        peps.add(new People(111, "M", 65.99));
        peps.add(new People(535, "F", 9.23));

        Collections.sort(peps);

        for (int i = 0; i < peps.size(); i++){
            System.out.println(peps.get(i));
        }
    }
}

Je pense que cela doit faire quelque chose avec le casting dans la méthode de comparaison, mais je jouais avec et je ne pouvais toujours pas trouver la solution

Dan
la source
1
N'utilisez pas de types bruts dans le nouveau code stackoverflow.com/questions/2770321/… ; utilisation Comparator<People>, Comparable<People>, List<People>, etc.
polygenelubricants
J'ai changé le comparateur <People> mais quand je change Arraylist <People>, le Collections.sort obtient une erreur
Dan
1
lisez ma réponse sur les 2 surcharges de sort. Si on vous dit d'utiliser Comparator<People>, utilisez l'argument 2 sort, et non l'argument 1 sort(qui requiert People implements Comparable<People>).
polygenelubricants

Réponses:

212

Il y a quelques problèmes avec votre classe d'exemple:

  • il s'appelle People alors qu'il a un priceet info(plus quelque chose pour les objets, pas pour les personnes);
  • en nommant une classe au pluriel de quelque chose, cela suggère qu'il s'agit d'une abstraction de plus d'une chose.

Quoi qu'il en soit, voici une démonstration de l'utilisation d'un Comparator<T>:

public class ComparatorDemo {

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
                new Person("Joe", 24),
                new Person("Pete", 18),
                new Person("Chris", 21)
        );
        Collections.sort(people, new LexicographicComparator());
        System.out.println(people);
        Collections.sort(people, new AgeComparator());
        System.out.println(people);
    }
}

class LexicographicComparator implements Comparator<Person> {
    @Override
    public int compare(Person a, Person b) {
        return a.name.compareToIgnoreCase(b.name);
    }
}

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person a, Person b) {
        return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
    }
}

class Person {

    String name;
    int age;

    Person(String n, int a) {
        name = n;
        age = a;
    }

    @Override
    public String toString() {
        return String.format("{name=%s, age=%d}", name, age);
    }
}

ÉDITER

Et une démo équivalente de Java 8 ressemblerait à ceci:

public class ComparatorDemo {

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
                new Person("Joe", 24),
                new Person("Pete", 18),
                new Person("Chris", 21)
        );
        Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name));
        System.out.println(people);
        Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1);
        System.out.println(people);
    }
}
Bart Kiers
la source
8
Le AgeComparator et des comparaisons similaires d'entiers peuvent être simplifiés pour retournera.age - b.age
Esko Luontola
13
@Esko: le "truc" de comparaison par soustraction est cassé pour le général int stackoverflow.com/questions/2728793/…
polygenelubricants
1
@Esko: à cause de ce que les lubrifiants polygéniques ont mentionné, je le fais simplement toujours comme ça, même si pour un âge (qui ne deviendra pas très grand) la soustraction comme vous le mentionnez ferait.
Bart Kiers
3
@saikiran, vous pouvez. Mais lors de la mise en œuvre Comparable, vous devez choisir un seul attribut à comparer. Dans le cas d'une personne, il existe de nombreux attributs sur lesquels on peut comparer: l'âge, la longueur, le sexe, les noms, etc. Dans ce cas, il est facile de fournir quelques comparateurs qui effectuent ces comparaisons.
Bart Kiers
1
@forsberg non, ce n'est pas obligatoire, mais (fortement) conseillé. Voir: stackoverflow.com/questions/94361/…
Bart Kiers
162

Voici un modèle très court pour effectuer le tri immédiatement:

Collections.sort(people,new Comparator<Person>(){
   @Override
   public int compare(final Person lhs,Person rhs) {
     //TODO return 1 if rhs should be before lhs 
     //     return -1 if lhs should be before rhs
     //     return 0 otherwise (meaning the order stays the same)
     }
 });

si c'est difficile à retenir, essayez de vous rappeler que c'est similaire (en termes de signe du nombre) à:

 lhs-rhs 

C'est au cas où vous voudriez trier par ordre croissant: du plus petit au plus grand nombre.

développeur android
la source
3
@ 40Plot, ceux-ci sont pour le positionnement, imaginez une règle ou un axe avec eux.
Eugene
Développeur @android, Merci d'avoir mentionné l'astuce pour se rappeler quelle valeur renvoyer pour quelle commande. :)
Gaur93
Meilleure explication de compare()tous les temps.
Muhammad Babar
importez également java.util.Comparator
Viraj Singh
@VirajSingh La question portait sur cette classe, donc bien sûr, c'est celle dont je parle ...
développeur android
39

Utilisez People implements Comparable<People>plutôt; ceci définit l'ordre naturel pour People.

A Comparator<People>peut également être défini en plus, mais ce People implements Comparator<People>n'est pas la bonne façon de faire les choses.

Les deux surcharges pour Collections.sortsont différentes:

  • <T extends Comparable<? super T>> void sort(List<T> list)
    • Trie les Comparableobjets en utilisant leur ordre naturel
  • <T> void sort(List<T> list, Comparator<? super T> c)
    • Trie tout ce qui utilise un Comparator

Vous confondez les deux en essayant de trier un Comparator(c'est encore une fois pourquoi cela n'a pas de sens Person implements Comparator<Person>). Encore une fois, pour utiliser Collections.sort, vous avez besoin de l'un de ceux-ci pour être vrai:

  • Le type doit être Comparable(utilisez le 1-arg sort)
  • Un Comparatorpour le type doit être fourni (utilisez les 2-args sort)

Questions connexes


N'utilisez pas non plus de types bruts dans le nouveau code . Les types bruts ne sont pas sûrs et sont fournis uniquement à des fins de compatibilité.

Autrement dit, au lieu de ceci:

ArrayList peps = new ArrayList(); // BAD!!! No generic safety!

vous devriez avoir utilisé la déclaration générique typeafe comme ceci:

List<People> peps = new ArrayList<People>(); // GOOD!!!

Vous constaterez alors que votre code ne se compile même pas !! Ce serait une bonne chose, car il y a quelque chose qui ne va pas avec le code ( Personnon implements Comparable<Person>), mais parce que vous avez utilisé le type brut, le compilateur n'a pas vérifié cela , et à la place vous obtenez un ClassCastExceptionau moment de l'exécution !!!

Cela devrait vous convaincre de toujours utiliser des types génériques de type sécurisé dans le nouveau code. Toujours.

Voir également

lubrifiants polygènes
la source
l'explication du comparateur vs comparable est très utile
abdel
18

Par souci d'exhaustivité, voici une compareméthode simple en une seule ligne :

Collections.sort(people, new Comparator<Person>() {
    @Override
    public int compare(Person lhs, Person rhs) {  
        return Integer.signum(lhs.getId() - rhs.getId());  
    }
});
Numéro quatre
la source
2
Apprécié pour l'utilisationsignum
msysmilu
1
@NumberFour "lhs.getId () - rhs.getId ()" ne doit pas être utilisé, il a des changements de débordement d'entier.
niraj.nijju
Pour la chaîne "return lhs.getName (). CompareTo (rhs.getName ());".
Ali Ahmed
1
Integer.compare(lhs.getId(), rhs.getId());est une meilleure approche. Comme @ niraj.nijju l'a mentionné, la soustraction peut provoquer un débordement.
narendra-choudhary
12

Java 8 a ajouté une nouvelle façon de créer des comparateurs qui réduit la quantité de code à écrire, Comparator.comparing . Consultez également Comparator.reversed

Voici un échantillon

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import static org.junit.Assert.assertTrue;

public class ComparatorTest {

    @Test
    public void test() {
        List<Person> peopleList = new ArrayList<>();
        peopleList.add(new Person("A", 1000));
        peopleList.add(new Person("B", 1));
        peopleList.add(new Person("C", 50));
        peopleList.add(new Person("Z", 500));
        //sort by name, ascending
        peopleList.sort(Comparator.comparing(Person::getName));
        assertTrue(peopleList.get(0).getName().equals("A"));
        assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("Z"));
        //sort by name, descending
        peopleList.sort(Comparator.comparing(Person::getName).reversed());
        assertTrue(peopleList.get(0).getName().equals("Z"));
        assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("A"));
        //sort by age, ascending
        peopleList.sort(Comparator.comparing(Person::getAge));
        assertTrue(peopleList.get(0).getAge() == 1);
        assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1000);
        //sort by age, descending
        peopleList.sort(Comparator.comparing(Person::getAge).reversed());
        assertTrue(peopleList.get(0).getAge() == 1000);
        assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1);
    }

    class Person {

        String name;
        int age;

        Person(String n, int a) {
            name = n;
            age = a;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }



}
rincer
la source
4

Vous souhaitez implémenter Comparable, pas Comparator. Vous devez implémenter la méthode compareTo. Vous êtes proche cependant. Le comparateur est une routine de comparaison «tierce». Comparable est que cet objet peut être comparé à un autre.

public int compareTo(Object obj1) {
  People that = (People)obj1;
  Integer p1 = this.getId();
  Integer p2 = that.getid();

  if (p1 > p2 ){
   return 1;
  }
  else if (p1 < p2){
   return -1;
  }
  else
   return 0;
 }

Remarque, vous voudrez peut-être vérifier les valeurs nulles ici pour getId..juste au cas où.

Will Hartung
la source
J'ai oublié de mentionner que c'était des devoirs, on m'a spécifiquement dit d'utiliser le comparateur
Dan
2

Voici un exemple de comparateur qui fonctionnera pour toute méthode à zéro argument qui renvoie un comparable. Est-ce que quelque chose comme ça existe dans un jdk ou une bibliothèque?

import java.lang.reflect.Method;
import java.util.Comparator;

public class NamedMethodComparator implements Comparator<Object> {

    //
    // instance variables
    //

    private String methodName;

    private boolean isAsc;

    //
    // constructor
    //

    public NamedMethodComparator(String methodName, boolean isAsc) {
        this.methodName = methodName;
        this.isAsc = isAsc;
    }

    /**
     * Method to compare two objects using the method named in the constructor.
     */
    @Override
    public int compare(Object obj1, Object obj2) {
        Comparable comp1 = getValue(obj1, methodName);
        Comparable comp2 = getValue(obj2, methodName);
        if (isAsc) {
            return comp1.compareTo(comp2);
        } else {
            return comp2.compareTo(comp1);
        }
    }

    //
    // implementation
    //

    private Comparable getValue(Object obj, String methodName) {
        Method method = getMethod(obj, methodName);
        Comparable comp = getValue(obj, method);
        return comp;
    }

    private Method getMethod(Object obj, String methodName) {
        try {
            Class[] signature = {};
            Method method = obj.getClass().getMethod(methodName, signature);
            return method;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

    private Comparable getValue(Object obj, Method method) {
        Object[] args = {};
        try {
            Object rtn = method.invoke(obj, args);
            Comparable comp = (Comparable) rtn;
            return comp;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }

}
John
la source
C'est vraiment super!
Zhurov Konstantin
2

Par souci d'exhaustivité.

Utilisation de Java8

people.sort(Comparator.comparingInt(People::getId));

si tu veux entrer descending order

people.sort(Comparator.comparingInt(People::getId).reversed());
Ankit Sharma
la source
Que se passe-t-il lorsqu'il y a deux objets dans la liste avec les mêmes valeurs de propriété utilisées en comparaison, qui, dans ce cas, est le People::getId?
Kok How Teh le
Vous pouvez ajouter une .thenComparing()clause en cas de conflit.
Ankit Sharma le
Que se passe-t-il dans le résultat s'il n'y a pas .thenComparing()?
Kok How Teh
Ensuite, cela dépend de l'ordre dans lequel les enregistrements étaient présents, en savoir plus sur geeksforgeeks.org/stability-in-sorting-algorithms
Ankit Sharma
Comment savoir si l'algorithme de tri utilisé est stable ou instable?
Kok How Teh
1
public static Comparator<JobSet> JobEndTimeComparator = new Comparator<JobSet>() {
            public int compare(JobSet j1, JobSet j2) {
                int cost1 = j1.cost;
                int cost2 = j2.cost;
                return cost1-cost2;
            }
        };
QuadBiker
la source
1

La solution peut être optimisée de la manière suivante: Premièrement, utilisez une classe interne privée car la portée des champs est d'être la classe englobante TestPeople afin que l'implémentation de la classe People ne soit pas exposée au monde extérieur. Cela peut être compris en termes de création d'une API qui attend une liste triée de personnes Deuxièmement, en utilisant l'expression Lamba (java 8) qui réduit le code, d'où l'effort de développement

Par conséquent, le code serait comme ci-dessous:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class TestPeople {
    public static void main(String[] args) {
        ArrayList<People> peps = new ArrayList<>();// Be specific, to avoid
                                                    // classCast Exception

        TestPeople test = new TestPeople();

        peps.add(test.new People(123, "M", 14.25));
        peps.add(test.new People(234, "M", 6.21));
        peps.add(test.new People(362, "F", 9.23));
        peps.add(test.new People(111, "M", 65.99));
        peps.add(test.new People(535, "F", 9.23));

        /*
         * Collections.sort(peps);
         * 
         * for (int i = 0; i < peps.size(); i++){
         * System.out.println(peps.get(i)); }
         */

        // The above code can be replaced by followin:

        peps.sort((People p1, People p2) -> p1.getid() - p2.getid());

        peps.forEach((p) -> System.out.println(" " + p.toString()));

    }

    private class People {
        private int id;

        @Override
        public String toString() {
            return "People [id=" + id + ", info=" + info + ", price=" + price + "]";
        }

        private String info;
        private double price;

        public People(int newid, String newinfo, double newprice) {
            setid(newid);
            setinfo(newinfo);
            setprice(newprice);
        }

        public int getid() {
            return id;
        }

        public void setid(int id) {
            this.id = id;
        }

        public String getinfo() {
            return info;
        }

        public void setinfo(String info) {
            this.info = info;
        }

        public double getprice() {
            return price;
        }

        public void setprice(double price) {
            this.price = price;
        }
    }
}
Akhil Gupta
la source
0

Vous devez utiliser la méthode de tri surchargé (peps, new People ())

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Test 
{
    public static void main(String[] args) 
    {
        List<People> peps = new ArrayList<>();

        peps.add(new People(123, "M", 14.25));
        peps.add(new People(234, "M", 6.21));
        peps.add(new People(362, "F", 9.23));
        peps.add(new People(111, "M", 65.99));
        peps.add(new People(535, "F", 9.23));

        Collections.sort(peps, new People().new ComparatorId());

        for (int i = 0; i < peps.size(); i++)
        {
            System.out.println(peps.get(i));
        }
    }
}

class People
{
       private int id;
       private String info;
       private double price;

       public People()
       {

       }

       public People(int newid, String newinfo, double newprice) {
           setid(newid);
           setinfo(newinfo);
           setprice(newprice);
       }

       public int getid() {
           return id;
       }

       public void setid(int id) {
           this.id = id;
       }

       public String getinfo() {
           return info;
       }

       public void setinfo(String info) {
           this.info = info;
       }

       public double getprice() {
           return price;
       }

       public void setprice(double price) {
           this.price = price;
       }

       class ComparatorId implements Comparator<People>
       {

        @Override
        public int compare(People obj1, People obj2) {
               Integer p1 = obj1.getid();
               Integer p2 = obj2.getid();

               if (p1 > p2) {
                   return 1;
               } else if (p1 < p2){
                   return -1;
               } else {
                   return 0;
               }
            }
       }
    }
michal
la source
Cela fonctionnerait, mais c'est un mauvais modèle. Une classe ne doit pas être son propre «comparateur».
Glorfindel
0

Voici ma réponse pour un simple outil de comparaison

public class Comparator {
public boolean isComparatorRunning  = false;
public void compareTableColumns(List<String> tableNames) {
    if(!isComparatorRunning) {
        isComparatorRunning = true;
        try {
            for (String schTableName : tableNames) {
                Map<String, String> schemaTableMap = ComparatorUtil.getSchemaTableMap(schTableName); 
                Map<String, ColumnInfo> primaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionOne(), schemaTableMap);
                Map<String, ColumnInfo> secondaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionTwo(), schemaTableMap);
                ComparatorUtil.publishColumnInfoOutput("Comparing table : "+ schemaTableMap.get(CompConstants.TABLE_NAME));
                compareColumns(primaryColMap, secondaryColMap);
            }
        } catch (Exception e) {
            ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage());
        }
        isComparatorRunning = false;
    }
}

public void compareColumns(Map<String, ColumnInfo> primaryColMap, Map<String, ColumnInfo> secondaryColMap) {
    try {
        boolean isEqual = true;
        for(Map.Entry<String, ColumnInfo> entry : primaryColMap.entrySet()) {
            String columnName = entry.getKey();
            ColumnInfo primaryColInfo = entry.getValue();
            ColumnInfo secondaryColInfo = secondaryColMap.remove(columnName);
            if(secondaryColInfo == null) {
                // column is not present in Secondary Environment
                ComparatorUtil.publishColumnInfoOutput("ALTER", primaryColInfo);
                isEqual = false;
                continue;
            }
            if(!primaryColInfo.equals(secondaryColInfo)) {
                isEqual = false;
                // Column not equal in secondary env
                ComparatorUtil.publishColumnInfoOutput("MODIFY", primaryColInfo);
            }
        }
        if(!secondaryColMap.isEmpty()) {
            isEqual = false;
            for(Map.Entry<String, ColumnInfo> entry : secondaryColMap.entrySet()) {
                // column is not present in Primary Environment
                ComparatorUtil.publishColumnInfoOutput("DROP", entry.getValue());
            }
        }

        if(isEqual) {
            ComparatorUtil.publishColumnInfoOutput("--Exact Match");
        }
    } catch (Exception e) {
        ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage());
    }
}

public void compareTableColumnsValues(String primaryTableName, String primaryColumnNames, String primaryCondition, String primaryKeyColumn, 
        String secTableName, String secColumnNames, String secCondition, String secKeyColumn) {
    if(!isComparatorRunning) {
        isComparatorRunning = true;
        Connection conn1 = DbConnectionRepository.getConnectionOne();
        Connection conn2 = DbConnectionRepository.getConnectionTwo();

        String query1 = buildQuery(primaryTableName, primaryColumnNames, primaryCondition, primaryKeyColumn);
        String query2 = buildQuery(secTableName, secColumnNames, secCondition, secKeyColumn);
        try {
            Map<String,Map<String, Object>> query1Data = executeAndRefactorData(conn1, query1, primaryKeyColumn);
            Map<String,Map<String, Object>> query2Data = executeAndRefactorData(conn2, query2, secKeyColumn);

            for(Map.Entry<String,Map<String, Object>> entry : query1Data.entrySet()) {
                String key = entry.getKey();
                Map<String, Object> value = entry.getValue();
                Map<String, Object> secondaryValue = query2Data.remove(key);
                if(secondaryValue == null) {
                    ComparatorUtil.publishColumnValuesInfoOutput("NO SUCH VALUE AVAILABLE IN SECONDARY DB "+ value.toString());
                    continue;
                }
                compareMap(value, secondaryValue, key);
            }

            if(!query2Data.isEmpty()) {
                ComparatorUtil.publishColumnValuesInfoOutput("Extra Values in Secondary table "+ ((Map)query2Data.values()).values().toString());
            }
        } catch (Exception e) {
            ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage());
        }
        isComparatorRunning = false;
    }
}

private void compareMap(Map<String, Object> primaryValues, Map<String, Object> secondaryValues, String columnIdentification) {
    for(Map.Entry<String, Object> entry : primaryValues.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        Object secValue = secondaryValues.get(key);
        if(value!=null && secValue!=null && !String.valueOf(value).equalsIgnoreCase(String.valueOf(secValue))) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Secondary Table does not match value ("+ value +") for column ("+ key+")");
        }
        if(value==null && secValue!=null) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in primary table for column "+ key);
        }
        if(value!=null && secValue==null) {
            ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in Secondary table for column "+ key);
        }
    }
}

private String buildQuery(String tableName, String column, String condition, String keyCol) {
    if(!"*".equalsIgnoreCase(column)) {
        String[] keyColArr = keyCol.split(",");
        for(String key: keyColArr) {
            if(!column.contains(key.trim())) {
                column+=","+key.trim();
            }
        }
    }
    StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.append("select "+column+" from "+ tableName);
    if(!ComparatorUtil.isNullorEmpty(condition)) {
        queryBuilder.append(" where 1=1 and "+condition);
    }
    return queryBuilder.toString();
}

private Map<String,Map<String, Object>> executeAndRefactorData(Connection connection, String query, String keyColumn) {
    Map<String,Map<String, Object>> result = new HashMap<String, Map<String,Object>>();
    try {
        PreparedStatement preparedStatement = connection.prepareStatement(query);
        ResultSet resultSet = preparedStatement.executeQuery();
        resultSet.setFetchSize(1000);
        if (resultSet != null && !resultSet.isClosed()) {
            while (resultSet.next()) {
                Map<String, Object> columnValueDetails = new HashMap<String, Object>();
                int columnCount = resultSet.getMetaData().getColumnCount();
                for (int i=1; i<=columnCount; i++) {
                    String columnName = String.valueOf(resultSet.getMetaData().getColumnName(i));
                    Object columnValue = resultSet.getObject(columnName);
                    columnValueDetails.put(columnName, columnValue);
                }
                String[] keys = keyColumn.split(",");
                String newKey = "";
                for(int j=0; j<keys.length; j++) {
                    newKey += String.valueOf(columnValueDetails.get(keys[j]));
                }
                result.put(newKey , columnValueDetails);
            }
        }

    } catch (SQLException e) {
        ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage());
    }
    return result;
}

}

Outil utilitaire pour le même

public class ComparatorUtil {

public static Map<String, String> getSchemaTableMap(String tableNameWithSchema) {
    if(isNullorEmpty(tableNameWithSchema)) {
        return null;
    }
    Map<String, String> result = new LinkedHashMap<>();
    int index = tableNameWithSchema.indexOf(".");
    String schemaName = tableNameWithSchema.substring(0, index);
    String tableName = tableNameWithSchema.substring(index+1);
    result.put(CompConstants.SCHEMA_NAME, schemaName);
    result.put(CompConstants.TABLE_NAME, tableName);
    return result;
}

public static Map<String, ColumnInfo> getColumnMetadataMap(Connection conn, Map<String, String> schemaTableMap) {
    try {
        String schemaName = schemaTableMap.get(CompConstants.SCHEMA_NAME);
        String tableName = schemaTableMap.get(CompConstants.TABLE_NAME);
        ResultSet resultSetConnOne = conn.getMetaData().getColumns(null, schemaName, tableName, null);
        Map<String, ColumnInfo> resultSetTwoColInfo = getColumnInfo(schemaName, tableName, resultSetConnOne);
        return resultSetTwoColInfo;
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

/* Number Type mapping
 * 12-----VARCHAR
 * 3-----DECIMAL
 * 93-----TIMESTAMP
 * 1111-----OTHER
*/
public static Map<String, ColumnInfo> getColumnInfo(String schemaName, String tableName, ResultSet columns) {
    try {
        Map<String, ColumnInfo> tableColumnInfo = new LinkedHashMap<String, ColumnInfo>();
        while (columns.next()) {
            ColumnInfo columnInfo = new ColumnInfo();
            columnInfo.setSchemaName(schemaName);
            columnInfo.setTableName(tableName);
            columnInfo.setColumnName(columns.getString("COLUMN_NAME"));
            columnInfo.setDatatype(columns.getString("DATA_TYPE"));
            columnInfo.setColumnsize(columns.getString("COLUMN_SIZE"));
            columnInfo.setDecimaldigits(columns.getString("DECIMAL_DIGITS"));
            columnInfo.setIsNullable(columns.getString("IS_NULLABLE"));
            tableColumnInfo.put(columnInfo.getColumnName(), columnInfo);
        }
        return tableColumnInfo;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static boolean isNullOrEmpty(Object obj) {
    if (obj == null)
        return true;
    if (String.valueOf(obj).equalsIgnoreCase("NULL")) 
        return true;
    if (obj.toString().trim().length() == 0)
        return true;
    return false;
}



public static boolean isNullorEmpty(String str) {
    if(str == null)
        return true;
    if(str.trim().length() == 0) 
        return true;
    return false;
}

public static void publishColumnInfoOutput(String type, ColumnInfo columnInfo) {
    String str = "ALTER TABLE "+columnInfo.getSchemaName()+"."+columnInfo.getTableName();
    switch(type.toUpperCase()) {
        case "ALTER":
            if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) {
                str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");";
            } else {
                str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));";
            }
            break;
        case "DROP":
            str += " DROP ("+columnInfo.getColumnName()+");";
            break;
        case "MODIFY":
            if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) {
                str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");";
            } else {
                str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));";
            }
            break;
    }
    publishColumnInfoOutput(str);
}

public static Map<Integer, String> allJdbcTypeName = null;

public static Map<Integer, String> getAllJdbcTypeNames() {
    Map<Integer, String> result = new HashMap<Integer, String>();
    if(allJdbcTypeName != null)
        return allJdbcTypeName;
    try {
        for (Field field : java.sql.Types.class.getFields()) {
            result.put((Integer) field.get(null), field.getName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return allJdbcTypeName=result;
}

public static String getStringPlaces(String[] attribs) {
    String params = "";
    for(int i=0; i<attribs.length; i++) { params += "?,"; }
    return params.substring(0, params.length()-1);
}

}

Classe d'informations de colonne

public class ColumnInfo {
private String schemaName;
private String tableName;
private String columnName;
private String datatype;
private String columnsize;
private String decimaldigits;
private String isNullable;
Vrajendra Singh Mandloi
la source
0

Deux corrections:

  1. Vous devez faire un ArrayListdes Peopleobjets:

    ArrayList<People> preps = new ArrayList<People>(); 
  2. Après avoir ajouté les objets aux préparations, utilisez:

    Collections.sort(preps, new CompareId());

Ajoutez également une CompareIdclasse comme:

class CompareId implements Comparator {  
    public int compare(Object obj1, Object obj2) {  
        People t1 = (People)obj1;  
        People t2 = (People)obj2;  

        if (t1.marks > t2.marks)  
            return 1;   
        else  
            return -1;
    }  
}
CodeurSam
la source
-7

Ne perdez pas de temps à mettre en œuvre l'algorithme de tri par vous-même. Au lieu; utilisation

Collections.sort () pour trier les données.

pooja jardosh
la source