集合操作在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)這樣和業務比較緊密的方法應該也會經常出現,大家可以根據自身項目情況,將這些模板類的代碼提取出來作爲公共工具包。
完整內容請參考github內rest-base項目內代碼。
https://github.com/q7322068/rest-base