集合操作
集合去重
- 若不考虑保留原顺序:利用set:
HashSet set = new HashSet(vector);
- 若要考虑保留原顺序:利用有序Set:
new ArrayList<XX>(new TreeSet<XX>())
、new ArrayList<XX>(new LinkedHashSet<XX>())
- 双重循环遍历,然后remove。复杂度O(n²)。遍历到i,看i+1以后是否重复。效率较低
- 利用List的contains()方法。效率较低
- 推荐用java8的streamAPI:
list.stream().distinct().collect(Collectors.toList())
List中删除指定元素
- List.remove()方法、removeAll()方法
- 普通for、while循环。可以用equals()方法判断是否为需要删除的元素,然后调用remove,当然remove后要记得下标减一(即i--)。也可以创建新List,把不删的放进去。
- 使用迭代器遍历元素,使用迭代器是可以直接删除的。注意使用foreach不能直接删除,否则会抛出ConcurrentModificationException
- 使用java8的streamAPI:
list.stream().filter(e -> !Object.equals(e, delete)).collect(Collectors.toList())
。类似的还有java8的:List.removeIf(e -> Object.equals(e, delete))
Conllection和conllections的区别
Collection:java中用于存储单列数据的集合接口,其子接口有List,Set(没有继承Collection接口!)
Conllections:是一个操作Set、List、和Map等集合的工具类(提供排序、搜索、反转、替换等功能)
List中插入和删除元素底层原理
List对数组进行动态扩容、增、删操作的核心都是需要调用本地方法System.arraycopy的,底层是调用lfd
,stfd
等汇编指令指令进行数组拷贝,分为引用拷贝和数据拷贝2个版本。
-
add插入到指定位置和remove删除指定位置元素
public void add(int index, E element) { rangeCheckForAdd(index); //检查index的值是否在0到size之间,可以为size。 ensureCapacityInternal(size + 1); // 看elementData的长度是否足够,不够扩容 //将elementData从index开始后面的元素往后移一位。 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } public E remove(int index) { rangeCheck(index); //如果index>=size抛出异常 modCount++; E oldValue = elementData(index); //获取删除元素的值 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved);//将index后面所有的元素往前移一位。 elementData[--size] = null; // Let gc do its work return oldValue;//返回要删除的原数。 }