Java开发常见错误

Arrays.asList()

List<String> list = Arrays.asList(arr);

Arrays.asList(arr)返回的list中的一个内部类—java.util.Arrays.ArrayList而不是—java.util.ArrayList这个类包含set(), get(), contains() 方法,但是不支持添加和移除元素。

private static class ArrayList<E> extends AbstractList<E> implements List<E>, Serializable, RandomAccess {
            ...
}

不过asList支持重载java.util.Arrays.ArrayList,正确的打开方式

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

判断数组是否包含某个元素

一般写法

for(String s: arr){
    if(s.equals(targetValue))
        return true;
}
return false;

但是这样的代码不具备可读性,我们想到集合Set里面包含contains方法:

//转换成set
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

但是这样还不够简洁,更好的方式

Arrays.asList(arr).contains(targetValue);

这就是为什么上一个问题中,Arrays要写一个内部类和实现一些方法

移除List中的元素

错误的移除方式

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
    list.remove(i);
}
System.out.println(list);
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));

for (String s : list) {
    if (s.equals("a"))
        list.remove(s);
}

查看ArrayList源码,发现他的数组结构不能一边移除一边遍历

正确的打开方式

  1. 使用迭代器
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();

    if (s.equals("a")) {
        iter.remove();
    }
}

2.倒序

for(int i=list.Count-1;i>=0;i--)
{
   if(list[i])
  {
    list.removeAt(i);
  }
}

3.多线程环境下 使用CopyOnWriteArrayList

public static void main(String args[]) {
    List<String> list = new CopyOnWriteArrayList<String>();
    list.add("A");
    list.add("B");

    for (String s : list) {
        if (s.equals("B")) {
            list.remove(s);
        }
    }
}

4.LinkedList、Set呢

public static void main(String args[]) {
    LinkedList<String> llist = new LinkedList<String>();
    llist.add("A");
    llist.add("B");

    for (String s : llist) {
        if (s.equals("B")) {
            llist.remove(s);
        }
    }
}

因为它们没有使用数组作为基础数据结构,所以它们不存在这个问题

使用集合的原始类型

1.原始类型是不安全的,如下:

public static void add(List list, Object o){
    list.add(o);
}
public static void main(String[] args){
    List<String> list = new ArrayList<String>();
    add(list, 10);
    String s = list.get(0);
}

代码运行时将会抛出java.lang.ClassCastException异常
2.Set和Set

public static void printSet(Set<?> s) {
    s.add(10);//this line is illegal 
    for (Object o : s) {
        System.out.println(o);
    }
}

但是修改成Set类型就不会报错

public static void printSet(Set s) {
    s.add("2");
    for (Object o : s) {
        System.out.println(o);
    }
}

但是这样使用又会存在最开始时候的风险

访问级别

因为贪图方便所有的访问级别都使用public,这样可以获取最高的访问权限,但是这样设计类是不合理的不符合开放封闭原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值