Java-ArrayList使用技巧---从第一个List中去除全部第二个List中与之重复的元素

需求:从 mAllList 中去除全部 mSubList 中与之重复的元素
测试数据:mAllList 中包含100000个无序无重复字符串,mSubList 中包含50000个无序无重复字符串

测试

方法1、ArrayList中提供的removeAll方法(效率最低)
mAllList.removeAll(mSubList);

某次测试耗时:185665mscode

方法2、双重循环(比方法一效率高)

双重循环分为内外两层循环,通过测试,将元素多的list放在外层循环效率更高(mSubList中的元素可能比mAllList多)(被删除元素的列表mAllList放在外层循环和内层循环的实现方式有些差异),这里的测试数据是mAllList中的元素多,实现以下:rem

int maxSize = mAllList.size();
for (int i = maxSize-1; i >=0; i--) {
    int size = mSubList.size();
    while (size > 0) {
        String s = mSubList.get(size-1);
        if (s.equals(mAllList.get(i))) {
            mSubList.remove(size-1);
            mAllList.remove(i);
            break;
        }
        size--;
    }
}

某次测试耗时:101510ms字符串

方法3、利用HashMap(效率最高)
//第一步:构建mAllList的HashMap
//将mAllList中的元素做为键,若是不是String类,须要实现hashCode和equals方法
//将mAllList中的元素对应的位置做为值
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < mAllList.size(); i++) {
    map.put(mAllList.get(i), i);
}
//第二步:利用map遍历mSubList,查找重复元素
//把mAllList中全部查到的重复元素的位置置空
for (int i = 0; i < mSubList.size(); i++) {
    Integer pos = map.get(mSubList.get(i));
    if (pos==null) {
        continue;
    }
    mAllList.set(pos, null);
}
//第三步:把mAllList中全部的空元素移除
for (int i = mAllList.size()-1; i>=0; i--) {
    if (mAllList.get(i)==null) {
        mAllList.remove(i);
    }
}

某次测试耗时:712msget

方法三的一些说明
  1. 方法三中初始化HashMap的时候已经知道了容量大小,理论上直接指定HashMap的大小避免扩容能够提升效率,可是测试发现并无提升,100000条数据都是几十毫秒
  2. 虽然方法三中HashMap存的值是整数,可是不要使用int pos = map.get(mSubList.get(i));取值,会崩溃
  3. 第二步中,使用Integer pos = map.get(mSubList.get(i));取值,而后判断 pos 是不是空来判断map中是否包含键是mSubList.get(i)的值,比用map.containsKey(key)来判断而后get取值少访问一次哈希表
  4. 第三步中,从mAllList尾部开始遍历移除

HashMap不了解的能够看下Java HashMap原理解析hash

相关文章
相关标签/搜索