1. 程式人生 > >spring boot專案實戰-集合操作

spring boot專案實戰-集合操作

集合操作在web應用開發中也是很常見的,目前也有一些比較方便的工具如java.util.Collections、org.apache.commons.collections.CollectionUtils等,但是根據自己公司專案開發中的具體情況提取一套更何用的集合操作工具類也是很有幫助的。

1、獲取在集合A而不在集合B內的元素(差集)

/**
 * 獲取在first集合內而不在second集合內的元素
 * @param first
 * @param second
 * @return
 */
public static List<String> getDiffList(Collection<String> first, Collection<String> second) {  
        long t = System.currentTimeMillis();
        Set<String> sameString = new HashSet<String>(second);
    List<String> result = new ArrayList<String>(first.size());  
    for (String s : first) { 
        if (!sameString.contains(s)) {  
            result.add(s);  
        }  
    }  
    if(System.currentTimeMillis() - t > 1){
            logger.debug("getDiffList with list first.size={},sencond.size={},use time={}ms",first.size(),second.size(),System.currentTimeMillis()-t);
    }

    return result;  
}
  • 比較重要的點是將second集合轉換為set,因為set判斷是否包含一個元素時間複雜度是O(1)

2、獲得在集合A內同時在集合B內的元素(交集)

/**
 * 獲得在list內同時在list2內的元素
 * 注意:在結果集內並不去重,如果list內本身有重複,返回的結果內可能包含相同元素
 * @param list
 * @param list2
 * @return
 */
public static List<String> getSameElements(Collection<String> list, Collection<String> list2) {
        long t = System.nanoTime();
        Set<String> set = new HashSet<String>(list2);
    List<String> sameElements = new ArrayList<String>(list.size());  
    for(String item : list){
        if(set.contains(item)){
            sameElements.add(item);
        }
    }
    if(logger.isDebugEnabled()){
        logger.debug("getSameElements list.size={},list2.size={},use time={}ns",list.size(),list2.size(),System.nanoTime()-t);
    }
    return sameElements;
}

3、將字串轉成list

/**
 * 輔助方法,將字串分割轉換為list
 * @author yangwenkui
 * @time 2017年1月10日 下午4:22:20
 * @param provinceIds
 * @return
 */
public static List<String> stringToList(String str,String split) {
    if(StringUtils.isBlank(str)){
        return Lists.newArrayList();
    }
    String[] arr = str.split(split);
    List<String> list = new ArrayList<String>(arr.length);
    for(String item : arr){
        if(StringUtils.isNotBlank(item)){
            list.add(item);
        }
    }
    return list;
}
  • 經常會有將id等用逗號連線儲存或傳輸,然後轉成集合進行操作的場景

4、獲取集合內每個實體的id

/**
 * 獲取集合內每個實體的id
 */
public static <T extends Serializable> List<T> getEntityIds(Collection<? extends BaseModel<T>> items) {
    List<T> ids = Lists.newArrayList();
    if(CollectionUtils.isEmpty(items)){
        return ids;
    }

    for(BaseModel<T> entity : items){
        T id = entity.getId();
        if(!ids.contains(id)){
            ids.add(id);
        }
    }
    return ids;
}
  • BaseModel是一個介面,定義了一個getId()方法

5、根據id列表找到集合內對應的實體

/**
 * 根據id列表找到集合內對應的實體
 * @return
 */
public static <T extends BaseModel<String>> List<T> select(Collection<T> list,Collection<String> selects){
    if(CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(selects)){
        return Lists.newArrayList();
    }
    List<T> selectList = Lists.newArrayList();
    for (String id : selects) {
        for(T entity : list){
            if(id.equals(entity.getId())){
                selectList.add(entity);
                break;
            }
        }
    }
    return selectList;
}

小結

  • 求集合的交集、差集註意查詢實現的時間複雜度,list查詢時間複雜度是O(n),HashSet查詢時間複雜度是O(1),建議使用HashSet。測試發現效率差了5倍以上(集合A(1500元素)、集合B(500元素));
  • 將集合轉為字串可以使用com.google.common.base.Joiner.on(“,”).join(list)實現,將字串轉為list可以使用上文內的方法;
  • 類似於獲取集合內每個元素的id(getEntityIds)、根據id列表找到集合內對應的實體(select)這樣和業務比較緊密的方法應該也會經常出現,大家可以根據自身專案情況,將這些模板類的程式碼提取出來作為公共工具包。