Rez*_*eza 3 java sorting algorithm
我有一个字符串数组,它是来自外部代码的类的实例,我宁愿不改变.
我还有一个通过调用每个对象上的函数生成的一组int.所以我有
A: [string1, string2, string3]
和
B: [40, 32, 34]
如何轻松地对A进行排序,使其按B的值排序.我有可用的提升.我想按顺序排序A:
[string2, string3, string1]
Run Code Online (Sandbox Code Playgroud)
在javascript中你可以这样做:
B.sort(function(a,b){return A[B.indexOf(a)] < A[B.indexOf(b)];});
Run Code Online (Sandbox Code Playgroud)
在java 8中,您可以这样做
与lambda:
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] ints = new int[]{40, 32, 34};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, (left, right) -> ints[stringListCopy.indexOf(left)] - ints[stringListCopy.indexOf(right)]);
Run Code Online (Sandbox Code Playgroud)
或者更好,与比较器:
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] ints = new int[]{40, 32, 34};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, Comparator.comparing(s -> ints[stringListCopy.indexOf(s)]));
Run Code Online (Sandbox Code Playgroud)
正如@wassgren所说,您可以使用流,但不必创建类,您可以只使用索引:
String[] strings = {"string1", "string2", "string3"};
int[] boosts = {40, 32, 34};
String[] sorted = IntStream.range(0, boosts.length).boxed()
.sorted(Comparator.comparingInt(i -> boosts[i]))
.map(i -> strings[i])
.toArray(String[]::new);
Run Code Online (Sandbox Code Playgroud)
首先,您创建一个索引流,然后根据提升对它们进行排序,然后获取该索引中的字符串。
简短的回答:我建议创建一个单独的类来保存有关实际String和增强(the int)的信息.如果您假设以下内容:
public class BoostString {
int boost;
String str;
public BoostString(int boost, String str) {
this.boost = boost;
this.str = str;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用a对数组进行排序Comparator,它对Java 8 Streaming API特别有用.
String[] strings = {"string1", "string2", "string3"};
int[] boosts = {40, 32, 34};
final String[] sorted = IntStream.range(0, boosts.length)
.mapToObj(i -> new BoostString(boosts[i], strings[i])) // Create the instance
.sorted(Comparator.comparingInt(b -> b.boost)) // Sort using a Comparator
.map(b -> b.str) // Map it back to a string
.toArray(String[]::new); // And return an array
Run Code Online (Sandbox Code Playgroud)
在Comparator以上示例中,使用所创建的Comparator.comparingInt这是一个创建的便利方式的方法Comparator使用Java 8整数.
说明:通常在比较Java中的对象时,您可以使用其中一个内置排序函数,例如Collections.sort您提供自己的排序函数Comparator.该Comparator接口非常简单,看起来像这样:
public interface Comparator<T> {
int compare(T o1, T o2);
// Other default methods for Java 8
}
Run Code Online (Sandbox Code Playgroud)
返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数.
当你排序Strings或int(或实际上是Integers)时,这是开箱即用的,因为它们是Comparable- 它们有一种内置的自然排序,而且String这是按字母顺序排列的,并且Integers按升序排序顺序(见的JavaDoc的Comparable).
另外,如果您使用的是第三方库,还有其他"对"或"元组"实现可用.您不必创建自己的"对" String和int.一个例子是来自Apache Commons的Pair类.
The*_*111 -2
创建一个TreeMap<Integer, List<ObjectTypeFromA>>,其中映射键是 B 中的值,映射值是 A 中的值(使用列表以允许重复键)。根据定义,它将按照 B 的顺序排序。
public static void main(String[] args) {
String[] strings = { "string1", "string2", "string3", "string4" };
int[] ints = { 40, 32, 32, 34 };
System.out.println(Arrays.toString(getSortedStringArray(strings, ints)));
}
public static String[] getSortedStringArray(String[] strings, int[] order) {
Map<Integer, List<String>> map = new TreeMap<>();
for (int i = 0; i < strings.length; i++) {
if (!map.containsKey(order[i])) {
map.put(order[i], new LinkedList<String>());
}
map.get(order[i]).add(strings[i]);
}
String[] ret = new String[strings.length];
int i = 0;
for (Map.Entry<Integer, List<String>> mapEntry : map.entrySet()) {
for (String s : mapEntry.getValue()) {
ret[i++] = s;
}
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)