2016-10-26 4 views
0

Я написал функцию слияния, которая объединяет два отсортированных списка в один отсортированный список. Ниже приведен сценарий для кода.Java generic merge

  1. Слияние списков [2, 4, 6], [3, 5, 6, 7] дает [2, 3, 4, 5, 6, 6, 7].
  2. Слияние списков [«Алиса», «Том»], [«Боб», «Ричард»] производит [«Алиса», «Боб», «Ричард», «Том»].
  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-х типов. Я должен выполнить самую общую возможную функцию слияния, считая, что списки входных данных отсортированы в порядке (в соответствии с естественным или заданным порядком)

+1

Обеспечить обычай 'Comparator' для' Collections.sort() 'для # 4 – kjsebastian

+0

Не заставляйте своих пользователей создавать поток, когда все, что им нужно, состоит в объединении двух списков. Ваш метод комбинирования должен иметь подпись 'static , U extends Comparable > Список comb (Список tList, Список uList)'. Используйте пользовательский компаратор, когда T и U - String и Integer. –

+0

Кроме того, весь смысл слияния списков _sorted_ заключается в том, что вам не придется сортировать их снова! –

ответ

1

Это похоже на то, что вы хотите? Там может быть более простой способ сделать это с помощью Stream и лучше использовать List<String> в отличие от ArrayList<String> по возможности, например List<String> list=new ArrayList<String>

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