how to sort every type array with a generic method in java?

问题: When i am compiling my code it is showing that E cannot be converted into int. public static <E> void sort(E[] ar){ int swap; for (int i = 0; i < ar.len...

问题:

When i am compiling my code it is showing that E cannot be converted into int.

public static <E> void sort(E[] ar){
    int swap;

    for (int i = 0; i < ar.length; i++) {
        for (int j = i; j < ar.length - 1; j++) {
            if (ar[j].compareTo(ar[j + 1])) {
                swap = ar[j];
                ar[j] = ar[j + 1];
                ar[j + 1] = swap;
            }
        }
    }
}

回答1:

The thing arrays in Java is: they are covariant.

These means that you can write a method that sorts an array of Number objects. This method will work for all kinds of number objects, Integer, Long,...

Thus: you can't solve this with generics easily, but using Number[] as type of that method parameter does the work nicely.

Of course, swap needs to be of type Number then.

When you insist on using generics, you should focus on using collection classes such as ArrayList / List instead of arrays, and then the use ? extends Number as generic type.


回答2:

First of all, your compile error comes from the type of the swap variable. On the line swap = ar[j];, you are trying to put a value of type E into a variable of type int. That is a type error. To fix that, you need to change the type of the swap variable by doing this:

E swap;

Now, if you want to sort objects of a generic type, you need to know how to compare them. In Java, there's two ways to do this. Either the type has to implement the Comparable interface, or you need to take an object of type Comparator as a parameter. Using a Comparator is more flexible because it makes the caller able to easily sort the same type in multiple ways (for example in chronological order and reversed chronological order).

To make your code work with a Comparable, you need to place a type constraint on your type parameter. Like this:

public static <E extends Comparable<E>> void sort(E[] ar){
    E swap;

    for (int i = 0; i < ar.length; i++) {
        for (int j = i; j < ar.length - 1; j++) {
            // Now you can use compareTo because E is a Comparable.
            // Also note the "< 0" because compareTo returns an int.
            if (ar[j].compareTo(ar[j + 1]) < 0) {
                swap = ar[j];
                ar[j] = ar[j + 1];
                ar[j + 1] = swap;
            }
        }
    }
}

Here's how you would do it with a Comparator:

public static <E> void sort(E[] ar, Comparator<E> comparator){
    E swap;

    for (int i = 0; i < ar.length; i++) {
        for (int j = i; j < ar.length - 1; j++) {
            if (comparator.compare(ar[j], ar[j + 1]) < 0) {
                swap = ar[j];
                ar[j] = ar[j + 1];
                ar[j + 1] = swap;
            }
        }
    }
}

You can call the function by creating Comparators like this:

// Sorting integers in ascending order.
sort(intArr, Comparator.naturalOrder());

// Sorting persons in descending order by age.
sort(personArr, Comparator.comparing(Person::getAge).reversed());

Note: Your code doesn't actually sort anything yet, because your algorithm is wrong. That is left for you to fix :)


回答3:

Java provides such a method in its standard library through a utility class called Arrays. It has got numerous overloaded form of a method named sort and can handle most of the widely used data types. You may want to check the API

e.g.

int[] integers = new int[] {1, 39, 22, 18, 50};
Arrays.sort(integers);
// to print sorted array
Arrays.stream(integers).boxed().collect(Collectors.toList())
.stream().forEach(System.out :: println);

For objects or data types that don't have a direct method, a generic method is supplied

  • public static void parallelSort(T[] a, Comparator cmp)

All you need to do is simply supply an implementation of Comparator. Check this sample

public class Sample{
    public String name;
    public int age;
    public Sample(String name, int age){
        this.name = name;
        this.age = age;
    }
    public String toString(){
        return String.format("Name: %s, Age: %s", name, age);
    }
}

public class Demo{
    public static void main(String[] args){
        Sample[] samples = Arrays.asList(new Sample("Sam", 23),
                                             new Sample("Hans", 13),
                                             new Sample("Ben", 53)
                                            ).toArray(new Sample[3]);

        Arrays.sort(samples, (a, b) -> a.age - b.age);
        Arrays.stream(samples).forEach(System.out :: println);
    }
}
  • 发表于 2019-03-18 14:01
  • 阅读 ( 227 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除