集合操作在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
网友评论