Java开发很容易犯的几个错误

来源:互联网 发布:多益网络的薪资福利 编辑:程序博客网 时间:2024/04/20 07:55

最近看到一个java程序员最常犯的10个错误的微博,很有意思。

自己就想总结,并后续添加自己开发中常见的错误。



1.将数组转化为列表

数组转为List有个常用的方法如下

List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");


Arrays.asList()会返回一个ArrayList对象,ArrayList类是Arrays的一个私有静态类,而不是java.util.ArrayList类,java.util.Arrays.ArrayList类有set()、get()、contains()方法,但是没有增加元素的方法,所以它的大小是固定的。

想要创建一个真正的ArrayList类,可以这样做:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList的构造方法可以接受一个集合类型,刚好它也是java.util.Arrays.ArrayList的超类。


2.在一个循环中删除一个列表中的元素

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);
这段代码估计很多人一眼就能看出问题,这样的输出结果是

[b,d]

你也许知道在循环中正确的删除多个元素的方法是使用迭代,并且你知道java中的foreach循环看起来像一个迭代器,但实际上并不是。考虑一下下面的代码:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a","b","c","d"));for(String s:list){    if(s.equals("a")){        list.remove(s);    }}
它会抛出一个ConcurrentModificationException异常。


相反下面的显示正常:

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();    }}

.next()必须在.remove()之前调用。在一个foreach循环中,编译器会使.next()在删除元素之后被调用,因此就会抛出ConcurrentModificationException异常,详情可以参考:http://blog.csdn.net/androidboy365/article/details/50540202/对此的分析。


3.在集合中使用原始类型

在Java中原始类型与无界通配符类型很容易混合在一起,拿Set来说,Set是一个原始类型,而Set<?>是无界的通配符类型。 考虑下面使用原始类型List作为参数的代码:

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

这段代码会抛出一个异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String    at ...

使用原生类型集合是危险的,这是因为原生类型集合跳过了泛型类型检查,并且不是安全的,在SetSet<?>和Set<Object>中有很大的不同。

4.ArrayList与LinkedList的对比

当程序员们不知道ArrayList与LinkedList的区别时,他们经常使用ArrayList,因为它看起来比较熟悉。然而,它们之前有巨大的性能差别。简而言之,如果有大量的增加删除操作并且没有很多的随机访问元素的操作,应该首先LinkedList。

ArrayList和Vector 几乎是使用了相同的算法,区别在于,ArrayList是线程不安全的,

ArrayList和LinkedList在性能上各 有优缺点,都有各自所适用的地方,总的说来可以描述如下: 

1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是 统一的,分配一个内部Entry对象。 

2.在ArrayList的 中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。 
3.LinkedList不 支持高效的随机元素访问。 
4.ArrayList的空 间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

List的相关知识可以参考一下这个:https://www.cnblogs.com/shanheyongmu/p/6439202.html

5.””还是构造器

有两种方式可以创建字符串

//1.使用字符串String x = "abc";//2.使用构造器String y = new String("abc");

有什么区别?

下面的例子会给出一个快速的答案:

String a = "abc";String b = "abc";System.out.println(a==b);//trueSystem.out.println(a.equals(b));//true String c = new String("abc");String d = new String("abc");System.out.println(c==d);//falseSystem.out.println(c.equals(d));//true






原创粉丝点击