Java 集合使用注意事项总结

Java 集合使用注意事项总结

https://javaguide.cn/java/collection/java-collection-precautions-for-use.html#%E5%BF%85%E7%9C%8B%E4%B8%93%E6%A0%8F

1. 集合判空

判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()==0 的方式。

使用isEmpty()方法具有更好的可读性,时间复杂度为O(1);使用size()方法的时间复杂度不固定,在某些情况下可以达到O(n)。

2. 集合转Map

在使用 java.util.stream.Collectors 类的 toMap() 方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。

class Person1 {
    String name;
    String phoneNumber;
}

List<Person1> list = new ArrayList<>();
list.add(new Person1("jack", "123456"));
list.add(new Person1("bob", "456789"));
Map<String, String> collect = list.stream().collect(
    Collectors.toMap(Person1::getName, Person1::getPhoneNumber)
);
/*
jack -> 123456
bob -> 456789
*/

3. 集合遍历

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。

fail-fast 机制 :多个线程对 fail-fast 集合进行修改的时候,可能会抛出ConcurrentModificationException。 即使是单线程下也有可能会出现这种情况,上面已经提到过。

Java8 开始,可以使用 Collection#removeIf()方法删除满足特定条件的元素,

removeIf() 中,需要重写一个过滤器,可以用lambda表达式。

List<Integer> li = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    li.add(i);
}

li.removeIf(new Predicate<Integer>() {
    @Override
    public boolean test(Integer integer) {
        return integer % 2 == 0;
    }
})
li.removeIf(t -> t % 2 == 0);

li.stream().forEach(t -> System.out.print(t + " "));
/*
1 3 5 7 9
*/

4. 集合去重

可以利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 Listcontains() 进行遍历去重或者判断包含操作。

set的去重使用的是hash值,单个元素去重的时间复杂度在没有哈希冲突时为O(1);list的contains() 方法去重采用的是迭代器去重,单个元素去重的时间复杂度最差情况下为O(n)

// Set 去重代码示例
public static <T> Set<T> removeDuplicateBySet(List<T> data) {

    if (CollectionUtils.isEmpty(data)) {
        return new HashSet<>();
    }
    return new HashSet<>(data);
}

// List 去重代码示例
public static <T> List<T> removeDuplicateByList(List<T> data) {

    if (CollectionUtils.isEmpty(data)) {
        return new ArrayList<>();

    }
    List<T> result = new ArrayList<>(data.size());
    for (T current : data) {
        if (!result.contains(current)) {
            result.add(current);
        }
    }
    return result;
}

5. 集合转数组

使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组

*注意:

toArray(T[] array) 方法的参数是一个泛型数组,如果 toArray 方法中没有传递任何参数的话返回的是 Object类 型数组。

String [] s= new String[]{
    "dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A"
};
List<String> list = Arrays.asList(s);
Collections.reverse(list);
//没有指定类型的话会报错
s=list.toArray(new String[0]);

new String[0] 作为方法参数,指定了泛型,大小为0是为了节省空间,因为其只是为了说明类型。

6. 数组转集合

使用工具类 Arrays.asList() 把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

*注意:

  1. Arrays.asList() 转换得到的是Array类型,而不是List类型。因此不支持add/remove等方法。

  2. Arrays.asList()泛型方法,因此传递的数组必须是对象数组,而不能是基本类型数组

int[] myArray1 = {1, 2, 3};
Integer[] myArray2 = {1, 2, 3};  // 正确
List myList1 = Arrays.asList(myArray1);
List myList2 = Arrays.asList(myArray2);
System.out.println(myList1.size()); // 1 list得到的是对象本身
System.out.println(myList2.size()); // 3 list得到的是对象中的元素

如何正确的将数组转为List集合?

List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
Integer [] myArray = { 1, 2, 3 };
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 = { 1, 2, 3 };
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值