【问题标题】:How to use Comparator in Java to sort如何在 Java 中使用 Comparator 进行排序
【发布时间】:2011-02-19 19:33:27
【问题描述】:

我学会了如何使用比较器,但我在使用比较器时遇到了困难。我的代码有错误:

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)

这是我的代码:

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

我认为它必须与比较方法中的强制转换有关,但我一直在玩它,但仍然找不到解决方案

【问题讨论】:

  • 不要在新代码中使用原始类型 stackoverflow.com/questions/2770321/… ;使用Comparator&lt;People&gt;Comparable&lt;People&gt;List&lt;People&gt;
  • 我更改了 Comparator,但是当我更改 Arraylist 时,Collections.sort 出现错误
  • 阅读我关于sort 的2 个重载的答案。如果您被告知使用Comparator&lt;People&gt;,则使用2-参数sort,而不是1-参数sort(需要People implements Comparable&lt;People&gt;)。

标签: java sorting comparator


【解决方案1】:

请改用People implements Comparable&lt;People&gt;;这定义了People 的自然顺序。

还可以另外定义一个Comparator&lt;People&gt;,但是People implements Comparator&lt;People&gt;不是正确的做事方式。

Collections.sort 的两个重载是不同的:

  • &lt;T extends Comparable&lt;? super T&gt;&gt; void sort(List&lt;T&gt; list)
    • 使用自然顺序对 Comparable 对象进行排序
  • &lt;T&gt; void sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c)
    • 使用兼容的Comparator 对任何内容进行排序

您通过尝试对Comparator 进行排序来混淆两者(这也是为什么Person implements Comparator&lt;Person&gt; 没有意义)。同样,要使用 Collections.sort,您需要满足以下条件之一:

  • 类型必须是Comparable(使用1-arg sort
  • 必须提供该类型的 Comparator(使用 2-args sort

相关问题


另外,不要在新代码中使用原始类型。原始类型是不安全的,它只是为了兼容性而提供的。

也就是说,而不是这个:

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

你应该像这样使用类型安全的泛型声明:

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

然后你会发现你的代码甚至无法编译!!这将是一件好事,因为代码有问题(Person 没有implements Comparable&lt;Person&gt;), 但由于您使用的是原始类型,因此编译器并未对此进行检查,而是在运行时得到ClassCastException!!!

这应该会说服您在新代码中始终使用类型安全的泛型类型。总是。

另见

【讨论】:

  • 比较器和可比较的解释很有用
【解决方案2】:

您想要实现 Comparable,而不是 Comparator。您需要实现 compareTo 方法。不过你很近。比较器是“第 3 方”比较例程。 Comparable 是这个对象可以与另一个对象进行比较。

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

注意,您可能需要在此处检查 getId 是否为空值。以防万一。

【讨论】:

  • 我忘了说这是作业,我被特别告知要使用比较器
【解决方案3】:

您的示例类有一些尴尬的事情:

  • 它被称为 People,而它有一个 priceinfo(更多的是对象,而不是人);
  • 当将一个类命名为某事物的复数形式时,它暗示它是不止一个事物的抽象。

无论如何,这里有一个如何使用Comparator&lt;T&gt;的演示:

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

编辑

等效的 Java 8 演示如下所示:

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

【讨论】:

  • AgeComparator 和类似的整数比较可以简化为返回a.age - b.age
  • @Esko:一般int stackoverflow.com/questions/2728793/… 的减法比较“技巧”已失效
  • @Esko:因为提到了 polygenelubricants,我只是总是那样做,即使对于一个年龄(不会变得很大)来说,像你提到的减法会做。
  • @saikiran,你可以。但是在实现Comparable 时,您必须选择一个属性进行比较。对于一个人,可以比较许多属性:年龄、长度、性别、姓名等。在这种情况下,很容易提供几个比较器来执行这些比较。
  • @forsberg 不,这不是强制性的,但(高度)建议。见:stackoverflow.com/questions/94361/…
【解决方案4】:

这是一个超短模板,可以立即进行排序:

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

如果很难记住,试着记住它类似于(就数字的符号而言):

 lhs-rhs 

如果您想按升序排序:从最小数字到最大数字。

【讨论】:

  • @40Plot,那些是用来定位的,用它们画一个尺子或轴。
  • @android developer ,感谢您提到记住要为哪个订单返回哪个值的技巧。 :)
  • compare() 的最佳解释。
  • 同时导入 java.util.Comparator
  • @VirajSingh 问题是关于这门课的,所以我说的当然是这个......
【解决方案5】:

为了完整起见,这里有一个简单的单行compare 方法:

Collections.sort(people, new Comparator<Person>() {
    @Override
    public int compare(Person lhs, Person rhs) {  
        return Integer.signum(lhs.getId() - rhs.getId());  
    }
});

【讨论】:

  • 感谢使用signum
  • @NumberFour " lhs.getId()-rhs.getId() " 不应该使用,它有整数溢出的变化。
  • 对于字符串“返回 lhs.getName().compareTo(rhs.getName());”。
  • Integer.compare(lhs.getId(), rhs.getId()); 是一种更好的方法。正如@niraj.nijju 提到的减法会导致溢出。
【解决方案6】:

你应该使用重载的 sort(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;
               }
            }
       }
    }

【讨论】:

  • 这会起作用,但这是一个糟糕的模式。一个类不应该是它自己的“比较器”。
【解决方案7】:
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;
            }
        };

【讨论】:

    【解决方案8】:

    解决方案可以通过以下方式进行优化: 首先,使用私有内部类作为字段的范围是封闭类 TestPeople,这样 People 类的实现不会暴露于外部世界。这可以理解为创建一个需要排序的人员列表的 API 其次,使用 Lamba 表达式(java 8)减少代码,从而减少开发工作

    因此代码如下:

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

    【讨论】:

      【解决方案9】:

      Java 8 添加了一种制作比较器的新方法,可以减少您必须编写的代码量,Comparator.comparing。另请查看Comparator.reversed

      这是一个示例

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

      【讨论】:

      【解决方案10】:

      这是一个比较器的示例,它适用于任何返回 Comparable 的零参数方法。 jdk 或库中是否存在类似的内容?

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

      【讨论】:

      • 真的很棒!
      【解决方案11】:

      不要浪费时间自己实现排序算法。而是使用Collections.sort() 对数据进行排序。

      【讨论】:

        【解决方案12】:

        两个更正:

        1. 您必须创建 ArrayListPeople 对象:

          ArrayList<People> preps = new ArrayList<People>(); 
          
        2. 将对象添加到preps后,使用:

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

        另外,添加一个CompareId 类为:

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

        【讨论】:

          【解决方案13】:

          这是我对一个简单的比较器工具的回答

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

          }

          同样的实用工具

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

          }

          列信息类

          public class ColumnInfo {
          private String schemaName;
          private String tableName;
          private String columnName;
          private String datatype;
          private String columnsize;
          private String decimaldigits;
          private String isNullable;
          

          【讨论】:

            【解决方案14】:

            为了完整性。

            使用 Java8

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

            如果你想descending order

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

            【讨论】:

            • 当列表中有两个具有相同属性值的对象进行比较时会发生什么,在这种情况下是People::getId
            • 发生冲突时可以添加.thenComparing()子句。
            • 如果没有.thenComparing(),结果会怎样?
            • 那么这取决于记录出现的顺序,阅读更多关于geeksforgeeks.org/stability-in-sorting-algorithms
            • 我怎么知道使用的排序算法是稳定还是不稳定?
            【解决方案15】:

            如果您使用的是 Java 8,那么最好使用如下代码:

            Comparator<People> comparator = Comparator.comparing(People::getName);
            

            然后简单地使用:

            Collections.sort(list, comparator);
            

            如果您使用的是 Java 7 或更低版本,则可以通过实现 compare 方法使用比较器来自定义排序顺序。

            例如:

            import java.util.Comparator;
            
            public class PeopleNameComparator implements Comparator<People> {
                @Override
                public int compare(People people1, People people2) {
                    return people1.getName().compareTo(people2.getName());
                }
            }
            

            然后像这样简单地使用:

            Collections.sort(list, new PeopleNameComparator);
            

            【讨论】:

              【解决方案16】:

              这里是比较器的 lambda 版本。这将根据长度对字符串列表进行排序。

              Collections.sort(str, (str1, str2) -> {
                  if(str1.length() < str2.length())
                      return 1;
                  else if(str2.length() < str1.length())
                      return -1;
                  else
                      return 0;
              });
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-11-14
                • 2019-04-07
                • 1970-01-01
                • 2015-07-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多