集合类:坑满地的List列表操作

将数组转换成List类数据结构,用Stream操作

第一个坑:不能直接使用 Arrays.asList 来转换基本类型数组,

第二个坑:Arrays.asList 返回的 List 不支持增删操作,如果增加或者删除会出现UnsupportedOperationException异常,

第三个坑:对原始数组的修改会影响到我们获得的那个 List

解决第三个坑,与初始化的数组进行解耦 【第三个意思:修改String[]数组会影响Arrays.asList之后的list的数据】
String[] arr = {"1", "2", "3"};
List list = new ArrayList(Arrays.asList(arr));
arr[1] = "4";
try {
    list.add("5");
} catch (Exception ex) {
    ex.printStackTrace();
}
log.info("arr:{} list:{}", Arrays.toString(arr), list);

使用 List.subList 进行切片操作居然会导致 OOM?

解释:和 Arrays.asList 的问题类似,List.subList 返回的子 List 不是一个普通的 ArrayList。这个子 List 可以认为是原始 List 的视图 如果不注意,很可能会因此产生 OOM 问题

原因解析:出现 OOM 的原因是,循环中的 1000 个具有 10 万个元素的 List 始终得不到回收,因为它始终被 subList 方法返回的 List 强引用。

private static List<List<Integer>> data = new ArrayList<>();

private static void oom() {
    for (int i = 0; i < 1000; i++) {
        List<Integer> rawList = IntStream.rangeClosed(1, 100000).boxed().collect(Collectors.toList());
        data.add(rawList.subList(0, 1));
    }
}

总:SubList中是使用的是ArrayList中视图,即是一种映射问题,修改SubList也会修改ArrayList中的数据 既然 SubList 相当于原始 List 的视图,那么避免相互影响的修复方式有两种:

第一种: //方式一:List subList = new ArrayList<>(list.subList(1, 4));

一定要让合适的数据结构做合适的事情

第一个误区是,使用数据结构不考虑平衡时间和空间。

搜索性能优化:

1:
优点: 搜索 ArrayList 的时间复杂度是 O(n),而 HashMap 的 get 操作的时间复杂度是 O(1)。所以,要对大 List 进行单值搜索的话,可以考虑使用 HashMap,其中 Key 是要搜索的值,Value 是原始对象,会比使用 ArrayList 有非常明显的性能优势

缺点: ArrayList内存占用比HashMap内存占用小,所以,在应用内存吃紧的情况下,我们需要考虑是否值得使用更多的内存消耗来换取更高的性能。这里我们看到的是平衡的艺术,空间换时间,还是时间换空间,只考虑任何一个方面都是不对的。
2: ArrayList和LinkedList的区别,有的时候知道这两者的区别,但是在真正用的时候,我们或许不能真正的发挥其中的作用 其中,ArrayList查询快 LinkList删除和增加快

总结LinkList:

讽刺的是,LinkedList 的作者约书亚 · 布洛克(Josh Bloch),在其推特上回复别人时说,虽然 LinkedList 是我写的但我从来不用,有谁会真的用吗?
(原因如下:)
抛开算法层面不谈,由于 CPU 缓存、内存连续性等问题,链表这种数据结构的实现方式对性能并不友好,即使在它最擅长的场景都不一定可以发挥威力

迭代元素时:

迭代器里面没有add方法,用迭代器时,可以删除原来集合的元素,但是!一定要用迭代器的remove方法而不是集合自身的remove方法,否则抛异常。

知识点

重点: 在用Iterator删除元素之后,在对Iterator重新进行赋值

假设数组初始长度时10,形成的结果就是:
Iterator 初始化 expectedModCount = 10;
然后删除某元素,数组长度9,Iterator 长度10,这时候如果调用next就会报错,所以,在这时候,重新初始化Iterator
Iterator 长度初始化为9,与数组长度一致,就避免了报错。
代码实现如下:
Iterator var2 = list.iterator();
while(var2.hasNext()) {
Integer integer = (Integer)var2.next();
if (integer.equals(2)){
list.remove(integer);
var2 = list.iterator();
}
}

你可能感兴趣的:(list,java)