我试图在Java中实现Generics的排序。 这是抽象类函数(T是我的"键"为了排序):
public abstract class Function<T extends Comparable<T>, S> {
abstract public T compute(S o);
}
这是Applier类,其方法&#34;适用&#34;根据&#34;计算&#34;:
的结果对列表进行排序import java.util.ArrayList;
import java.util.Iterator;
public class Applier<T extends Comparable<T>, S> {
ArrayList<S> apply(ArrayList<S> input, Function<T, S> function) {
ArrayList<T> output = new ArrayList<>();
for(Iterator<S> it = input.iterator(); it.hasNext(); ){
output.add(function.compute(it.next()));
}
T tmpTi, tmpTj;
S tmpSi, tmpSj;
for(int i=0; i<input.size(); i++) {
for(int j=i+1; j<input.size(); j++) {
if(output.get(i).compareTo(output.get(j))>0) {
tmpTi = output.get(i);
tmpTj = output.get(j);
output.remove(j);
output.remove(i);
output.add(i, tmpTi);
output.add(i, tmpTj);
tmpSi = input.get(i);
tmpSj = input.get(j);
input.remove(j);
input.remove(i);
input.add(i, tmpSj);
input.add(j, tmpSi);
}
}
}
return input;
}
}
我的问题是:有没有更聪明的方法来进行这种排序,也许没有使用bubblesort? 这里也是主要的课程:
public static void main(String[] args) {
Applier a = new Applier<>();
StringLength strlen = new StringLength();
ArrayList<String> array = new ArrayList<>();
array.add("Hola");
array.add("Man");
array.add("randomstufff");
array.add("Zerrone");
array.add("Info3a");
System.out.println("Order by length");
System.out.print("before: ");
System.out.println(array);
a.apply(array, strlen); //works on original object
System.out.print("After: ");
System.out.println(array);
答案 0 :(得分:1)
请注意,在冒泡排序中交换元素的方式存在错误:当将元素重新插入output
时,您错放了i
和j
。此外,不要删除和重新插入元素,只需使用set(index, element)
覆盖上一个条目。
此外,不要使用两个列表并保持这些列表同步,最好只使用Map
。
public static class Applier<T extends Comparable<T>, S> {
ArrayList<S> apply(ArrayList<S> input, Function<T, S> function) {
Map<S, T> compareBy = new HashMap<>();
for (S s : input) {
compareBy.put(s, function.compute(s));
}
for(int i=0; i<input.size(); i++) {
for(int j=i+1; j<input.size(); j++) {
if (compareBy.get(input.get(i)).compareTo(compareBy.get(input.get(j))) > 0) {
S tmpS = input.get(j);
input.set(j, input.get(i));
input.set(i, tmpS);
}
}
}
return input;
}
}
当然,排序已经在Java中实现了。所以除了学习如何编码之外,你应该总是使用内置函数。在Java 8中,它只是一行:
Collections.sort(array, Comparator.comparing(String::length));
但请注意,Comparator.comparing
将为每个成对比较调用比较器函数(即,对于一个不错的排序算法, 2nlogn 次序)。如果该函数在计算上非常昂贵,您可能希望使用Map
自行缓存它。
Map<String, Integer> compareBy = array.stream().collect(Collectors.toMap(s -> s, s -> s.length()));
Collections.sort(array, Comparator.comparing((String s) -> compareBy.get(s)));
答案 1 :(得分:0)
基本上你想基于其他一些数组对数组进行排序。如果引入包含值和函数结果的包装器对象,则可以使用Collections.sort
,并对其进行排序。
这是使用Java 8流API的解决方案:
public class Applier<T extends Comparable<T>, S> {
static class Wrapper<T extends Comparable<T>,S> implements Comparable<Wrapper<T,S>> {
T key;
S value;
Wrapper(S s, Function<T, S> function) {
this.key = function.compute(s);
this.value = s;
}
public int compareTo(Wrapper<T,S> that) {
return key.compareTo(that.key);
}
}
ArrayList<S> apply(ArrayList<S> input, Function<T, S> function) {
S[] sorted = (S[]) IntStream.range(0, input.size())
.mapToObj(i -> new Wrapper<T,S>(input.get(i), function))
.sorted()
.map(b -> b.value).toArray();
input.clear();
input.addAll(Arrays.asList(sorted));
return input;
}
}