2013-09-25 42 views
1

我正在使用以下代碼合併兩個ArrayList。代碼工作並給了我想要的結果,但我想要一個更高效的版本。這裏是條件。提高合併兩個ArrayList的性能

  1. 方法接受兩個列表,並且兩個列表具有以遞減順序(5,4,3,2)
  2. 方法接受一個整數來決定所得ArrayList的大小的元件。
  3. 第一個輸入列表大小永遠不會超過生成的ArrayList的大小。

代碼:

public ArrayList<Integer> mergeList(ArrayList<Integer> first,ArrayList<Integer> second, int n){ 
    //case 1: when both list are null. 
    if(first == null && second == null) 
     return null; 
    //case 2: when first list is null but second list have elements 
    else if(first == null && second != null){ 
     return second.size() >=n ? new ArrayList<Integer>(second.subList(0, n)) : second; 
    } 
    //case 3: when first list have record and second list is null 
    else if(first != null && second == null){ 
     return first; 
    } 
    //case 4: when both list have elements 
    else { 
     first.addAll(second); 
     Collections.sort(first); 
     Collections.reverse(first); 
     return first.size()>=n ? new ArrayList<Integer>(first.subList(0, n)) : first; 
    } 
} 

}

+2

這是不必要的複雜。 'ArrayList'根據需要擴展,所以不需要預先分配它(不需要參數'int n')。您應該只在開始時分配一次結果列表。我認爲這裏的目標是寫一個適當的合併。連接列表和排序並不是最好的解決方案。如果由於某種原因,您仍然希望這樣做,請按降序排序,以便您不必倒轉列表。 –

+0

@JimGarrison參數n是需求的一部分,所以我無法避免它,但我接受了您的建議並更新了我的代碼。最新的代碼被上傳。 – Ashish

+2

生成的列表是否也需要按相反順序排列?在輸入或結果中是否允許重複? – Bohemian

回答

1

這取決於你的意思是「更高效」。

在什麼方面?內存,CPU,可讀性?

基於您的代碼上面,我正在做以下假設:

  • 可讀性比純粹的性能/內存消耗更重要,沒有任何剖析測量/要求「程序優化的第一條原則:不要第二條規則優化(僅限專家!):不要這樣做。「 - 邁克爾A.傑克遜
  • 體型的空對象模式在返回null
  • 重複的元素是理想的/所需的
  • 使用一個Comparator執行反向 排序

private List<Integer> mergeList(List<Integer> list1, List<Integer> list2, final int newSize) { 

    // Enforce null object pattern 
    if (list1 == null) { 
     list1 = Collections.emptyList(); 
    } 
    if (list2 == null) { 
     list2 = Collections.emptyList(); 
    } 

    // If duplicates are not desirable, a TreeSet would perform automatic sorting. 
    List<Integer> result = new ArrayList<Integer>(list1); 
    result.addAll(list2); 

    Comparator<Integer> reverseSortComparator = new Comparator<Integer>() { 

     @Override 
     public int compare(final Integer o1, final Integer o2) { 
      return o2.compareTo(o1); 
     } 
    }; 

    Collections.sort(result, reverseSortComparator); 

    if (result.size() > newSize) { 
     return result.subList(0, newSize); 
    } else { 
     return result; 
    } 
} 
+0

非常感謝。這是我期望實施的 – Ashish

0

它看起來像你想保留的firstsecond內容。如果你不是,那麼這將做就好了你,使你的代碼速度更快,更具可讀性:

public ArrayList<Integer> mergeList(ArrayList<Integer> first,ArrayList<Integer> second, int maxLength){ 

    //case 1: when both list are null. 
    if(first == null && second == null) 
     return null; 
    //case 2: when first list is null but second list have elements 
    else if(first == null && second != null){ 
     return second; 
    } 
    //case 3: when first list have record and second list is null 
    else if(first != null && second == null){ 
     return first; 
    } 
    //case 4: when both list have elements 
    else if(first != null && second != null){ 
     first.addAll(second); 
     Collections.sort(first); //want to merge these two line into one 
     Collections.reverse(first); 
    } 
    return (ArrayList) first.size() > maxLength ? first.subList(0, n) : first; 
} 

之所以這樣,是快是因爲每一個addAll(),爪哇必須通過所有元素的,將它們複製到tempList。我保留了Collections.reverse調用,因爲它似乎需要將數據按逆序排序。

+0

nope我不想保留第一和第二的內容,但我確實想返回列表中的大小n,列表的第三個參數。 – Ashish

+0

@Ashish,我重新添加了截斷步驟。這將修剪列表中的最小元素,使列表不超過長度maxLength。 –

+0

感謝,但子列表(0,N)將不會返回列表ArrayList中。 – Ashish