关于java中List集合的使用时常遇到的几个问题

本文详细解析了List与Set的异同,介绍了synchronizedList及其与Vector的区别,并探讨了Array.asList()的特点及注意事项,最后讲解了如何在遍历过程中安全地删除ArrayList中的元素。

一.List与Set的异同

Lsit和Set都是继承自Collection接口。都是用来储存一组相同的元素。

List的特点:元素有放入的顺序,元素可以重复。有顺序---即先放入的元素排在前面。

Set的特点:元素无放入的顺序,元素不可以重复。

无顺序---先放入的元素不一定在前面。

不可重复---相同的元素在set中只会保留一份,所以有些场景可以利用set去重复。不过需要注意的是set在元素插入的时候是要有一定的方法判断元素是否重复,这个方法很重要,决定了set可以存哪些元素

二.什么是synchronizedList?他和Vector有什么区别?

SynchronizedList是java.util.Collections中的一个静态内部类。

eg. List<String> TEST_LIST = Collections.synchronizedList(new ArrayList<String>());

在多线程的环境下可以直接使用Vector类,也可以使用Collections.synchronizedList(List list)方法来返回一个线程安全的List

1.如果使用add方法,那么他们的扩容机制不一样(类似arraylist和Vector的区别)

2.SynchronizedList可以指定锁定的对象。即锁粒度是同步代码块。而Vector的锁粒度是同步方法

3.SynchronizedList有很好的扩展性和兼容功能。他可以将所有的list子类转成线程安全的类。

4.使用SynchronizedList的时候,进行遍历时需要手动进行同步处理

5.SynchronizedLsit可以指定锁定的对象

三.通过Array.asList()获得的List有什么特点,使用时应该注意什么?

1.asList()得到的只是个Arrays的内部类,一个原来数组的视图List,因此如果对他进行增删操作会报错

2.用ArrayList的构造器可以将其转变成为一个真正的ArrayList

四.如何在遍历的同时删除ArrayList中的元素

1.错误场景:使用增强for循环,在循环 的过程中删除非基本数据类型之后,继续循环list会报ConcurrentModificationException

像这种情况下,在删除元素后马上跳出循环也不会报错(break)

eg.list.remove(l);

break;

2.使用普通的for循环不会报错,但是删除元素后,被删除的元素索引发生了变化,假设被删除的list中有10个元素,当删除了第三个元素,第四个元素就变成了第三个,第五个元素就变成了第四个,但是程序下一步的循环的索引是第四个了,这时候取到的元素是第五个元素

3.使用Iterator的方式可以顺利的删除和遍历元素

注意:删除元素的时候要使用Iterator 的remove()方法移除当前的对象,如果使用List 的remove方法同样会出现异常

 

 

 

<think>嗯,用户想知道如何从JavaList对象中提取成员变量重组为新List。首先,我得回忆一下Java中的集合操作。可能的方法有循环遍历Java 8的Stream API,或者第三方库比如Guava和Apache Commons。 首先想到的是传统方法,用for循环逐个取出成员变量,添加到新List。这种方法简单直接,适合所有Java版本,但代码量稍多。然后,Java 8的Stream API可以用map和collect来简化,代码更简洁。用户可能已经使用Java 8或更高版本,所以Stream是推荐的方式。 还要考虑第三方库的情况。比如Guava的Lists.transform,不过需要处理惰性求值的问题,可能不是最佳选择。Apache Commons的CollectionUtils.collect也是选项,但需要引入额外依赖,用户可能不想添加库。 另外,需要注意空指针的问题。如果对象中的成员变量可能为null,或者List中有null元素,需要处理异常。比如在Stream中使用filter过滤掉null对象,或者在映射时进行空检查。引用中提到NullHandler接口可以处理null的情况,但那是OGNL的特定实现,可能在Java标准库中不适用,但可以提醒用户注意空值处理。 用户的问题可能涉及到性能,特别是处理大数据量时。Stream API在并行处理上有优势,可以提到parallelStream。但也要注意线程安全和顺序问题。 还要考虑类型安全,确保提取的成员变量类型正确,新List的类型匹配。例如,使用map(ClassName::getField)时,返回的类型是否正确。 可能还需要提到使用构造新List时的初始化,比如预先指定容量以提高效率,尤其是在数据量大的情况下。不过通常Stream的collect(Collectors.toList())已经足够高效。 最后,总结几种方法的优缺点,帮助用户根据具体情况选择。比如,如果代码简洁性重要,推荐Stream;如果兼容旧版本Java,用传统循环;如果已用第三方库,可以相应使用。 相关问题部分,用户可能想了解性能比较、处理复杂对象、并行处理、不可变集合或空值处理。这些问题扩展了主题,帮助用户深入应用。</think>### 如何从Java对象List中提取成员变量生成新List #### 方法一:传统循环遍历 ```java List<YourObject> originalList = ...; // 原始对象列表 List<String> resultList = new ArrayList<>(); for (YourObject obj : originalList) { resultList.add(obj.getMemberVariable()); } ``` - 优点:兼容所有Java版本 - 缺点:代码冗余,需手动管理集合 #### 方法二:Java 8+ Stream API ```java List<String> resultList = originalList.stream() .map(YourObject::getMemberVariable) .collect(Collectors.toList()); ``` - 优点:代码简洁,支持链式操作 - 缺点:需Java 8+环境 #### 方法三:第三方工具库(Guava) ```java List<String> resultList = Lists.transform(originalList, YourObject::getMemberVariable); ``` - 注意:Guava的转换是惰性求值,立即访问需复制到新列表[^1] #### 方法四:Apache Commons ```java CollectionUtils.collect(originalList, new Transformer() { public Object transform(Object input) { return ((YourObject) input).getMemberVariable(); } }, resultList); ``` #### 特殊场景处理 1. **过滤空值**: ```java List<String> filteredList = originalList.stream() .filter(Objects::nonNull) .map(YourObject::getMemberVariable) .filter(Objects::nonNull) .collect(Collectors.toList()); ``` 2. **类型转换**: ```java List<Integer> numericList = originalList.stream() .map(obj -> Integer.parseInt(obj.getStrValue())) .collect(Collectors.toList()); ``` 3. **并行处理**: ```java List<String> parallelList = originalList.parallelStream() .map(YourObject::getMemberVariable) .collect(Collectors.toList()); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值