You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现基于输入参数类型的动态返回类型,编写支持任意类型列表的按键排序通用函数?

要实现这个通用的排序函数,我们可以借助Java的泛型来支持任意类型的待排序列表,同时保证返回的列表类型和输入完全一致。下面分两种方案来实现——一种基于Java原生API,另一种沿用你原来的Guava工具类思路做泛化改造。


方案一:Java原生API实现(无需第三方库)

这个方案不依赖任何第三方工具,完全用Java标准库完成,更轻量化。核心思路是先把键和对应值配对,按键排序后,再将值填入和输入同类型的列表中。

import java.util.*;

public class GenericSortUtil {

    public static <T> List<T> sort(List<Integer> keys, List<T> valuesToSort) {
        // 先校验两个列表长度一致,避免索引越界
        if (keys.size() != valuesToSort.size()) {
            throw new IllegalArgumentException("Keys and values lists must have the same size");
        }

        // 生成键值对列表,保留原始索引的对应关系
        List<Map.Entry<Integer, T>> keyValuePairs = new ArrayList<>();
        for (int i = 0; i < keys.size(); i++) {
            keyValuePairs.add(new AbstractMap.SimpleEntry<>(keys.get(i), valuesToSort.get(i)));
        }

        // 按键的自然顺序排序
        keyValuePairs.sort(Map.Entry.comparingByKey());

        // 创建与输入同类型的列表实例
        List<T> sortedValues;
        try {
            sortedValues = valuesToSort.getClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // 如果无法实例化(比如私有构造),降级使用ArrayList
            sortedValues = new ArrayList<>();
        }

        // 将排序后的值添加到新列表
        for (Map.Entry<Integer, T> pair : keyValuePairs) {
            sortedValues.add(pair.getValue());
        }

        return sortedValues;
    }

    // 测试示例
    public static void main(String[] args) {
        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);
        System.out.println(sortedValues); // 输出 [E, C, A, D, B]

        // 测试整数列表类型
        List<Integer> numValues = Arrays.asList(30, 50, 20, 40, 10);
        List<Integer> sortedNums = sort(keys, numValues);
        System.out.println(sortedNums); // 输出 [10, 20, 30, 40, 50]

        // 测试LinkedList输入,返回同类型列表
        LinkedList<Double> doubleValues = new LinkedList<>(Arrays.asList(3.1, 5.2, 2.3, 4.4, 1.5));
        LinkedList<Double> sortedDoubles = (LinkedList<Double>) sort(keys, doubleValues);
        System.out.println(sortedDoubles.getClass().getSimpleName()); // 输出 LinkedList
        System.out.println(sortedDoubles); // 输出 [1.5, 2.3, 3.1, 4.4, 5.2]
    }
}

关键点说明:

  • 用<T>泛型参数让函数支持任意类型的List<T>输入
  • 通过valuesToSort.getClass().newInstance()尝试创建同类型列表,严格保证返回类型和输入一致;如果实例化失败(比如列表类有私有构造),则降级使用ArrayList
  • 提前做长度校验,避免运行时出现索引越界错误

方案二:基于Guava的泛化改造(沿用原有思路)

如果你项目中已经依赖Guava,可以把原来的String专属版本改成泛型版本,同时保留返回类型一致性:

import com.google.common.collect.*;
import java.util.List;

public class GuavaGenericSortUtil {

    public static <T> List<T> sort(List<Integer> keys, List<T> valuesToSort) {
        if (keys.size() != valuesToSort.size()) {
            throw new IllegalArgumentException("Keys and values lists must have the same size");
        }

        Multimap<Integer, T> multiMap = LinkedListMultimap.create();
        for (int i = 0; i < keys.size(); i++) {
            multiMap.put(keys.get(i), valuesToSort.get(i));
        }

        // 创建同类型的列表实例
        List<T> sortedValues;
        try {
            sortedValues = valuesToSort.getClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            sortedValues = Lists.newArrayList();
        }

        // 按键的自然顺序遍历,添加对应的值
        for (Integer key : Ordering.natural().sortedCopy(multiMap.keys())) {
            sortedValues.addAll(multiMap.get(key));
        }

        return sortedValues;
    }

    // 测试示例
    public static void main(String[] args) {
        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);
        System.out.println(sortedValues); // 输出 [E, C, A, D, B]
    }
}

关键点说明:

  • 将原来的String替换为泛型<T>,让Multimap支持任意类型的值
  • 同样处理了返回列表的类型一致性问题,优先复用输入列表的类型
  • 保留了你原有的Guava使用逻辑,适合已经依赖Guava的项目

额外注意事项

  • 如果keys中有重复值,两个方案都会保留对应值的原始顺序(LinkedListMultimap和ArrayList的键值对都是按插入顺序保存的),符合稳定排序的预期
  • 若需要自定义键的排序逻辑(比如倒序),可以把排序器作为参数传入函数,进一步增强通用性

内容的提问来源于stack exchange,提问作者PebNischl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:13:12