基于输入参数类型的动态返回类型

发布于 2025-01-17 23:39:53 字数 1081 浏览 1 评论 0原文

我正在尝试编写一个小函数,该功能根据另一个元素进行两个列表,并根据另一个元素进行分类。因此,类似:

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可能是不同事物的列表,例如整数,浮点或其他列表。理想情况下,我希望我的程序获取我投入的任何列表,根据对其进行排序,然后返回与输入相同类型的列表。我该怎么做?如果修复了值的类型,则排序本身将很简单,例如

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;
}

,仅当value是预期类型的​​列表时才有效。

I'm trying to write a small function that takes two lists and sorts one based on the elements of the other. So something like:

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);

would result in a sorted list [E, C, A, D, B].

However, valuesToSort might be a list of something different, like integers, floats or other lists. Ideally, I would want my program to take any list I throw at it, sort it according to keys, and then return a list of the same type as the input. How would I do that? If the type of values were fixed, the sorting itself would be straightforward, like for example

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;
}

but this only works if values is a list of the expected type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

横笛休吹塞上声 2025-01-24 23:39:54

您可以使用泛型来实现此目的,如下所示:

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。这将在运行时发生。

You can use Generics for this as follow:

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;
}

Now, when you pass list of strings, the generic T would be considered as String. When you pass list of integers, T would become Integer. This will happen at runtime.

記柔刀 2025-01-24 23:39:54

这是一种方法。我假设这些键可能有重复的数字,例如 [3, 5, 2, 2, 1]。否则,更简单的算法将占上风。

  • 使用引用示例的keys 列表对从0 到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();
}

Here is one way. I am presuming that the keys could have duplicate numbers like [3, 5, 2, 2, 1]. Otherwise, simpler algorithms would prevail.

  • Sort the values from 0 to keys.size() using the keys list
  • for the cited example, this will result in the following stream of integers. [4 2 0 3 1]
  • then use those to index into the values list.
  • this will then yield the desired order.
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);

prints

[E, C, A, D, B]

The generic method

  • make it static
  • the value list is just indexed so that can be any type T
  • the key list must be of type 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();
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文