基于输入参数类型的动态 return 类型
Dynamic return type based on input argument type
我正在尝试编写一个小函数,它接受两个列表并根据另一个列表的元素对一个列表进行排序。所以像:
List<Integer> keys = Arrays.asList(3, 5, 2, 4, 1);
List<String> valuesToSort = Arrays.asList("A", "B", "C", "D", "E");
List<String> sortedValues = sort(keys, valuesToSort);
将生成排序列表 [E, C, A, D, B]
。
但是,valuesToSort
可能是一个不同的列表,例如整数、浮点数或其他列表。理想情况下,我希望我的程序接受我扔给它的任何列表,根据 keys
对它进行排序,然后 return 一个与输入相同类型的列表。我该怎么做?如果 values
的类型是固定的,那么排序本身就会很简单,例如
public List<String> sort(List<Integer> keys, List<String> values){
Multimap<Integer, String>> multiMap = LinkedListMultimap.create();
for (int i = 0; i < keys.size(); i++) {
multiMap.put(keys.get(i), values.get(i));
}
List<String>> sortedValues = Lists.newArrayList();
for (Integer key : Ordering.natural().sortedCopy(multiMap.keys())) {
for (String value : multiMap.get(key)) {
sortedValues.add(value);
}
}
return sortedValues;
}
但这仅在 values
是预期类型的列表时有效。
您可以为此使用泛型,如下所示:
public List<T> sort(List<Integer> keys, List<T> values){
Multimap<Integer, T>> multiMap = LinkedListMultimap.create();
for (int i = 0; i < keys.size(); i++) {
multiMap.put(keys.get(i), values.get(i));
}
List<T> sortedValues = Lists.newArrayList();
for (Integer key : Ordering.natural().sortedCopy(multiMap.keys())) {
for (T value : multiMap.get(key)) {
sortedValues.add(value);
}
}
return sortedValues;
}
现在,当您传递字符串列表时,通用 T
将被视为 String
。当您传递整数列表时,T
将变为 Integer
。这将在运行时发生。
这是一种方法。我假设这些键可能有重复的数字,如 [3, 5, 2, 2, 1]
。否则,将采用更简单的算法。
- 使用
keys
列表 对 0 to keys.size()
中的值进行排序
- 对于引用的示例,这将导致以下整数流。
[4 2 0 3 1]
- 然后使用这些索引到值列表中。
- 这将产生所需的顺序。
List<Integer> keys = Arrays.asList(3, 5, 2, 4, 1);
List<String> valuesToSort =
Arrays.asList("A", "B", "C", "D", "E");
List<String> result = sort(keys, valuesToSort);
System.out.println(result);
打印
[E, C, A, D, B]
泛型方法
- 使其静态化
- 值列表只是索引因此可以是任何类型
T
- 密钥列表必须是
Integer
类型
public static <T> List<T> sort(List<Integer> keys, List<T> values){
return IntStream.range(0, keys.size()).boxed()
.sorted(Comparator.comparing(keys::get))
.map(values::get).toList();
}
我正在尝试编写一个小函数,它接受两个列表并根据另一个列表的元素对一个列表进行排序。所以像:
List<Integer> keys = Arrays.asList(3, 5, 2, 4, 1);
List<String> valuesToSort = Arrays.asList("A", "B", "C", "D", "E");
List<String> sortedValues = sort(keys, valuesToSort);
将生成排序列表 [E, C, A, D, B]
。
但是,valuesToSort
可能是一个不同的列表,例如整数、浮点数或其他列表。理想情况下,我希望我的程序接受我扔给它的任何列表,根据 keys
对它进行排序,然后 return 一个与输入相同类型的列表。我该怎么做?如果 values
的类型是固定的,那么排序本身就会很简单,例如
public List<String> sort(List<Integer> keys, List<String> values){
Multimap<Integer, String>> multiMap = LinkedListMultimap.create();
for (int i = 0; i < keys.size(); i++) {
multiMap.put(keys.get(i), values.get(i));
}
List<String>> sortedValues = Lists.newArrayList();
for (Integer key : Ordering.natural().sortedCopy(multiMap.keys())) {
for (String value : multiMap.get(key)) {
sortedValues.add(value);
}
}
return sortedValues;
}
但这仅在 values
是预期类型的列表时有效。
您可以为此使用泛型,如下所示:
public List<T> sort(List<Integer> keys, List<T> values){
Multimap<Integer, T>> multiMap = LinkedListMultimap.create();
for (int i = 0; i < keys.size(); i++) {
multiMap.put(keys.get(i), values.get(i));
}
List<T> sortedValues = Lists.newArrayList();
for (Integer key : Ordering.natural().sortedCopy(multiMap.keys())) {
for (T value : multiMap.get(key)) {
sortedValues.add(value);
}
}
return sortedValues;
}
现在,当您传递字符串列表时,通用 T
将被视为 String
。当您传递整数列表时,T
将变为 Integer
。这将在运行时发生。
这是一种方法。我假设这些键可能有重复的数字,如 [3, 5, 2, 2, 1]
。否则,将采用更简单的算法。
- 使用
keys
列表 对 - 对于引用的示例,这将导致以下整数流。
[4 2 0 3 1]
- 然后使用这些索引到值列表中。
- 这将产生所需的顺序。
0 to keys.size()
中的值进行排序
List<Integer> keys = Arrays.asList(3, 5, 2, 4, 1);
List<String> valuesToSort =
Arrays.asList("A", "B", "C", "D", "E");
List<String> result = sort(keys, valuesToSort);
System.out.println(result);
打印
[E, C, A, D, B]
泛型方法
- 使其静态化
- 值列表只是索引因此可以是任何类型
T
- 密钥列表必须是
Integer
类型
public static <T> List<T> sort(List<Integer> keys, List<T> values){
return IntStream.range(0, keys.size()).boxed()
.sorted(Comparator.comparing(keys::get))
.map(values::get).toList();
}