2013-09-25 43 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