求2个Integer对象 有序列表 的交集


public class CollectionUtils
{

    /**
     * 合并2个 有序列表的交集
     * @param c1
     * @param c2
     * @return List
     */
   public static List<Integer> retainOrderListAll(List<Integer>c1,List<Integer>c2 )
   {
        if(c1.size()<=c2.size()){//长度小的列表作为参考列表
            return retain(c1,c2);
        }
       else{
            return retain(c2,c1);
        }
   }

    /**
     * 比较前提是2个列表都是 升序排序好的...
     * @param minList
     * @param maxList
     * @return List
     */
private static List<Integer> retain(List<Integer> minList,List<Integer> maxList){

            bre1:for( Iterator<Integer> it = minList.iterator();it.hasNext(); )
            {
                      Integer int1 = it.next(); //当前参照值
                      bre2:for(Iterator<Integer> it2 = maxList.iterator();it2.hasNext();)
                      {
                          Integer int2 = it2.next(); //当前比较值;

                               ////////===比较2个数值的大小 根据比较的结果进行3种操作=====//////
                     //// (1)如果 相等 那么就移除list2中当前值,进入list1下一轮循环
                     //// (2)如果 参照值int1 大于 比较值int2 那么删除小值int2 继续list2中的循环查找 -->(1)
                     //// (3)如果 参照值int1 小于 比较值int2 那么删除小值int1 继续list1中的循环-->(1);


                    //============值 匹配时==================== ;
                                if(int1.equals(int2)){
                                    it2.remove();//list2中比较过的数值 直接删除...避免下次再次比较该数值;
                                    continue bre1;//进入下一轮list1循环;
                                }
                    //=============未 匹配时=====================;
                                if(int1 > int2){
                               //参照值大于比较值时;
                                    it2.remove();
                                    continue;
                                }
                               //参照值小于 比较值时,说明此参照值肯定不会被匹配,直接删除 进入下一轮list1循环
                               if(int1 < int2){
                                    it.remove();
                                    continue bre1;
                               }
                       }
                   //=================list2为空时 list1中的所有剩余值全部移除 该判断要放在后面,以防列表被清空时,当前的it 没被移除直接进入下一次循环了;
                    if(maxList.size()==0){
                            it.remove();
                            continue;
                    }
             }
             return minList;
    }
}


测试过
50000 条记录 和 33333条记录的两个列表 求交集时间是1800ms左右
100000条 和 66666条记录的两个列表 求交集时间是8000ms左右

因为it.remove 需要重新整理索引 所以速度耗费了很大一块

修正后:
public class CollectionUtils
{

    /**
     * 合并2个 求有序列表的交集
     * 列表为null时候 那么就视为全集;
     * @param c1
     * @param c2
     * @return List
     */
   public static List<Integer> retainOrderListAll(List<Integer>c1,List<Integer>c2 )
   {
      //===========是否存在null列表对象==============
       if(c1==null && c2==null){//都为null
           return null;
       }
       else if(c1==null && c2!=null){//其中一个为null 返回另一个列表
           return c2;
       }
       else if(c1!=null && c2 == null){
           return c1;
       }
       //==========列表对象都不为null时======================
       if(c1.size()<=c2.size()){//长度小的列表作为参考列表
            return retain(c1,c2);
        }
       else{
            return retain(c2,c1);
        }
   }

    /**
     * 比较前提是2个列表都是 升序排序好的...
     * @param minList
     * @param maxList
     * @return List
     */
private static List<Integer> retain(List<Integer> minList,List<Integer> maxList){

//        int compCount = 0;//比较次数;

           List<Integer> r = new ArrayList<Integer>();

            int index1 = 0;
            int size1 = minList.size();

            int index2 = 0;
            int size2 = maxList.size();

           loop1: for( ;index1 < size1;index1++){

            loop2:  for( ;index2 < size2;index2++ )
                       {
                                   if(minList.get(index1).equals( maxList.get( index2))){
                                        r.add( minList.get( index1));
                                        index2++;
                                        continue loop1;
                                   }
                                   if(minList.get(index1) > maxList.get( index2)){

                                       continue;
                                   }
                                     if(minList.get(index1) < maxList.get( index2)){
                                         continue loop1;
                                   }
                       }
           }
                 return r;
    }

    /**
     * 判断列表 是否是一个空列表对象;
     * 且非null;
     * @param list
     * @return boolean
     */
   public static boolean isEmptyList(List list){
       if(list!=null && list.size()==0){
           return true;
       }else{
           return false;
       }
   }
}

测试后速度提高了几百倍
基本是线性复杂度  最高复杂度是 M+N
耗时在 几十ms

你可能感兴趣的:(有序列表 交集)