【问题标题】:implementing comprable method in a generic way in Java for sorting在Java中以通用方式实现可比较的方法以进行排序
【发布时间】:2020-10-11 06:51:04
【问题描述】:

我正在尝试实现一个通用的选择排序,它可以接受任何对象并对其进行排序。我可以向编译器保证,无论我在比较什么对象,都会为其实现 compareTo 方法。但是我得到以下代码的编译错误

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class SelectionSortGenerics implements Comparable<E> {

    private <E> void swap(E[] a, int i, int j) {
        if (i != j) {
            E temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    }

    public <E> void selectionSort(E[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            // find index of smallest element
            int smallest = i;
            for (int j = i + 1; j < a.length; j++) {
                if (a[j].compareTo(a[smallest])<=0) {
                    smallest = j;
                }
            }

            swap(a, i, smallest);  // swap smallest to front
        }
    }

    public static void main(String[] args){
        SelectionSortGenerics firstsort = new SelectionSortGenerics();

        Integer[] arr = {3,4,1,5};
        System.out.println("before sorting int: "+ Arrays.toString(arr));
        firstsort.selectionSort(arr);
        System.out.println("After sorting int : "+Arrays.toString(arr));
         String[] arr1= {"acd","ded","dal","bad","cle"};
         System.out.println("before sorting String: "+ Arrays.toString(arr1));
         firstsort.selectionSort(arr1);
         System.out.println("After sorting String : "+Arrays.toString(arr1));
         Character[] arr2= {'c','e','a','d','c'};
         System.out.println("before sorting char: "+ Arrays.toString(arr2));
         firstsort.selectionSort(arr2);
         System.out.println("After sorting char : "+Arrays.toString(arr2));
    }
}

如您所见,我在 main 方法中传递的对象是 Integer、String 和 Character,其中有 compareTo 方法。如何使上述代码工作。任何地方都需要铸造? 感谢您的帮助。

【问题讨论】:

    标签: java sorting generics comparable compareto


    【解决方案1】:

    以下内容对我有用。我所做的只是删除类声明中的&lt;E&gt;,并在选择排序中将&lt;E&gt; 更改为&lt;E extends Comparable&lt;E&gt;&gt;

    类声明中的泛型&lt;E&gt; 是不必要的,并且可能会造成混淆,因为您的类实际上不需要是泛型的。只有类中的方法是泛型的,而不是类本身。

    其次,selectionSort方法要求传入的元素类型与自身具有可比性。你可以通过E extends Comparable&lt;E&gt;来代表这个。

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    
    public class SelectionSortGenerics {
    
        private <E> void swap(E[] a, int i, int j) {
            if (i != j) {
                E temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    
        public <E extends Comparable<E>> void selectionSort(E[] a) {
            for (int i = 0; i < a.length - 1; i++) {
                // find index of smallest element
                int smallest = i;
                for (int j = i + 1; j < a.length; j++) {
                    if (a[j].compareTo(a[smallest])<=0) {
                        smallest = j;
                    }
                }
    
                swap(a, i, smallest);  // swap smallest to front
            }
        }
    
        public static void main(String[] args){
            SelectionSortGenerics firstsort = new SelectionSortGenerics();
    
            Integer[] arr = {3,4,1,5};
            System.out.println("before sorting int: "+ Arrays.toString(arr));
            firstsort.selectionSort(arr);
            System.out.println("After sorting int : "+Arrays.toString(arr));
             String[] arr1= {"acd","ded","dal","bad","cle"};
             System.out.println("before sorting String: "+ Arrays.toString(arr1));
             firstsort.selectionSort(arr1);
             System.out.println("After sorting String : "+Arrays.toString(arr1));
             Character[] arr2= {'c','e','a','d','c'};
             System.out.println("before sorting char: "+ Arrays.toString(arr2));
             firstsort.selectionSort(arr2);
             System.out.println("After sorting char : "+Arrays.toString(arr2));
        }
    }
    

    【讨论】:

    • 为获得最佳效果,请使用&lt;E extends Comparable&lt;? super E&gt;&gt;
    • 另外,您的swap 方法可以用签名private void swap(Object[] a, int i, int j) 编写,将方法内的E 替换为ObjectE 不是必需的。
    • @newacct 实际上这行不通,因为我正在分配回数组。传递除 Object[] 之外的任何内容都会导致错误。
    • 不,不会的。 (不信就试试吧。)
    • 有趣。我忘记了数组存储仅在运行时进行类型检查。由于在这种情况下运行时类型匹配,因此没有错误。我认为通用版本更清楚地表达了意图。
    【解决方案2】:
     **Refer below method to implement generic sorting.You just have to pass list in sortElements    and  the name of the field on you want to enable sorting**
     /**
     * This method is used to sort the elements based on the fieldName specified.
     * Sorting order is Ascending order.
     * 
     * @param resultList
     *            e.g., List of ProductBrand
     * @param fieldName
     *            e.g., productBrandName list will be sorted according to this
     *            fieldName.
     * @throws Exception
     */
    public static <Type> void sortElements(List<Type> resultList, final String fieldName, final boolean isDesc) throws Exception
    {
      Collections. sort(resultList, new Comparator<Type>()
      {
              @Override
              public int compare(Type o1, Type o2)
             {
                    return compareValue(o1, o2);
             }
    
              private int compareValue(Type o1, Type o2)
             {
                    int returnValue = 0;
                    try
                   {
                          Field field = o1.getClass().getDeclaredField(fieldName);
                           boolean accessible = field.isAccessible();
                          field.setAccessible( true);
                          Object objectO1 = field.get(o1);
                          Object objectO2 = field.get(o2);
                           if (objectO1 instanceof Number)
                          {
                                  if ((objectO1 != null && objectO2 != null)
                                               && (objectO1 instanceof Integer || objectO1 instanceof Long || objectO1 instanceof Byte))
                                 {
                                        returnValue = Long.valueOf(objectO1 + "").compareTo(Long. valueOf(objectO2 + ""));
                                 }
                                  else if ((objectO1 != null && objectO2 != null) && (objectO1 instanceof Double || objectO1 instanceof Float))
                                 {
    
                                        returnValue = Double.valueOf(objectO1 + "").compareTo(Double. valueOf(objectO2 + ""));
    
                                 }
                          }
                           else if (objectO1 instanceof String || objectO1 instanceof Character)
                          {
                                  if ((objectO1 != null) && objectO2 != null)
                                 {
                                        returnValue = normalizedString(String.valueOf(objectO1)).compareToIgnoreCase(
                                                       normalizedString(String.valueOf(objectO2)));
                                 }
                          }
                          field.setAccessible(accessible);
                   }
                    catch (Exception e)
                   {
                          System. out.println("Error occured while sorting elements");
                   }
    
                    if (isDesc)
                   {
                           if (returnValue > 0)
                          {
                                  return -1;
                          }
                           else if (returnValue < 0)
                          {
                                  return 1;
                          }
                   }
                    return returnValue;
             }
      });
    

    }

     /**
     * This methods Normalizes the input string. Here we remove accent from the
     * character so that we can sort the string properly using normal characters.
     * 
     * @param str
     *            example <B> BSH Electrodom�sticos Espa�a S.A. </b>
     * @return Normalized String . <B> ex : BSH Electrodomesticos Espana S.A.</b>
     * 
     */
     public static String normalizedString(String str)
     {
       if (!isNullOrBlank(str))
      {
             String nfdNormalizedString = Normalizer. normalize(str, Normalizer.Form.NFD );
             Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
              return pattern.matcher(nfdNormalizedString).replaceAll("");
      }
       else
      {
              return "" ;
      }
     }
    
     /**
     * This function checks that the value is blank or null.
     * 
     * @param value
     *            value to be checked
     * @return true if value is blank or null
     */
     public static boolean isNullOrBlank(String value)
     {
       boolean retFlag = false;
       if (value == null || value.trim().equals("") || value.trim().equals("null" ))
      {
             retFlag = true;
      }
       return retFlag;
     }
    

    【讨论】:

      【解决方案3】:

      注意:下面实现的排序算法仅适用于长度为 2 的幂的数组。您也可以将此技术用于其他排序算法:

      方法一:Using java.util.Comparator

      方法二:Using T extends Comparable

      主要方法:Main method

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 2023-02-23
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        相关资源
        最近更新 更多