【问题标题】:Java generic mergeJava 泛型合并
【发布时间】:2016-10-26 06:30:47
【问题描述】:

我编写了一个合并函数,将两个排序列表合并为一个排序列表。以下是代码的场景。

  1. 合并列表 [2, 4, 6], [3, 5, 6, 7] 生成 [2, 3, 4, 5, 6, 6, 7]。
  2. 合并列表 [“Alice”、“Tom”]、[“Bob”、“Richard”] 生成 [“Alice”、“Bob”、“Richard”、“Tom”]。
  3. 合并列表 [2.3, 4.5], [2,5] 生成 [2, 2.3, 4.5, 5]。
  4. 合并列表 [“A”, “XYZ”, “AXTU”] 和 [2, 4, 6](其中第一个列表按字长排序,在合并操作中,如果字符串长度在第一个列表与第二个列表中的数字相同,字符串在前)产生 [“A”, 2, “XYZ”, “AXTU”, 4, 6];

     public static void testCombine() {
        ArrayList<ArrayList<String>> mainList = new ArrayList<>();
        ArrayList<String> list1 = new ArrayList<String>(Arrays.asList("Alice", "Tom"));
        ArrayList<String> list2 = new ArrayList<String>(Arrays.asList("Bob", "Richard"));
        mainList.add(list1);
        mainList.add(list2);
        System.out.println(combine(mainList.stream()));
    }
    
    private static <T extends Comparable<? super T>> ArrayList<T> combine(Stream<ArrayList<T>> stream) {
        return stream.reduce((x, y) -> {
            x.addAll(y);
            Collections.sort(x);
            return x;
        }).get();
    }
    

但是,我没有得到 3 和 4 类型的结果。我必须实现最通用的合并功能,假设输入列表是有序的(根据自然或指定的顺序)

【问题讨论】:

  • 为#4 提供自定义ComparatorCollections.sort()
  • 当您的用户只想合并两个列表时,不要强迫他们创建流。您的 combine 方法应具有签名 static &lt;T extends Comparable&lt;T&gt;, U extends Comparable&lt;U&gt;&gt; List&lt;Object&gt; combine(List&lt;T&gt; tList, List&lt;U&gt; uList)。当 T 和 U 是 String 和 Integer 时使用自定义比较器。
  • 另外,合并 sorted 列表的全部意义在于您不必再次对它们进行排序!

标签: java generics


【解决方案1】:

这和你想要的一样吗?使用Stream 可能有更简单的方法来执行此操作,最好尽可能使用List&lt;String&gt; 而不是ArrayList&lt;String&gt;,例如List&lt;String&gt; list=new ArrayList&lt;String&gt;

public static void testCombine() {
    List<String> stringList1 = new ArrayList<>(Arrays.asList("A", "AB", "XYZ", "AXTU"));
    List<Integer> integerList2 = new ArrayList<>(Arrays.asList(2, 4, 6));
    System.out.println(Main.combine(stringList1, integerList2, new MergeTwoTypes<String, Integer>() {
        @Override
        public Function<? super Integer, ? extends String> map() {
            return (x)->Integer.toString(x);
        }

        @Override
        public boolean isVal2Larger(String val, Integer val2) {
            return val.length()>val2;
        }
    }));
    List<Double> list1 = new ArrayList<>(Arrays.asList(2.3, 4.5));
    List<Integer> list2 = new ArrayList<>(Arrays.asList(2, 5));
    System.out.println(Main.combine(list1, list2, new MergeTwoTypes<Double, Integer>() {
        @Override
        public Function<? super Integer, ? extends Double> map() {
            return ((Integer x) -> new Double(x));
        }

        @Override
        public boolean isVal2Larger(Double val, Integer val2) {
            return val>val2;
        }
    }));
}

private static <T, U> List<T> combine(List<T> vals1, List<U> vals2, MergeTwoTypes<T, U> mergeTwoTypes) {
    List<T> list=new ArrayList<>();
    int vals2Index=0;
    for(T val:vals1) {
        for(; vals2Index<vals2.size(); vals2Index++) {
            U val2=vals2.get(vals2Index);
            if(mergeTwoTypes.isVal2Larger(val, val2)) {
                list.add(mergeTwoTypes.map().apply(val2));
            }
            else {
                break;
            }
        }
        list.add(val);
    }
    for(; vals2Index<vals2.size(); vals2Index++) {
        U val2=vals2.get(vals2Index);
        list.add(mergeTwoTypes.map().apply(val2));
    }
    return list;
}

private static <T extends Comparable<? super T>> List<T> combine(List<T> vals1, List<T> vals2) {
    List<T> list=new ArrayList<>();
    list.addAll(vals1);
    list.addAll(vals2);
    Collections.sort(list);
    return list;
}

interface MergeTwoTypes<T,U> {
    boolean isVal2Larger(T val, U val2);
    Function<? super U, ? extends T> map();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-24
    • 2016-07-26
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多