`
tomcat_oracle
  • 浏览: 317011 次
社区版块
存档分类
最新评论

Java程序员常犯的10个错误

    博客分类:
  • Java
阅读更多

#1. 把Array转化成ArrayList

把Array转化成ArrayList,程序员经常用以下方法:

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

Arrays.asList() 实际上返回一个ArrayList,但是这个ArrayList是Arrays的一个内部私有类,而不是java.util.ArrayList类。这个私有类java.util.Arrays.ArrayList有set(), get(), contains()方法,但是不能够添加新的元素。它的大小是固定的。如果你想要一个java.util.ArrayList,正确的方法是:

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

java.util.ArrayList的构造函数可以接受一个集合类型。java.util.Arrays.ArrayList也继承了集合类型,所以可以作用参数使用。

#2. 检查数组是否包含一个值

开发人员经常做的是:

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

这个代码是工作的,但没有没有效率。把列表转换成set没有必要,需要额外的时间。正确的方法是:

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

或者,一个简单的loop:

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

第一种比第二种更具有可读性。

#3. 在循环中删除一个列表元素

考虑下面的代码,迭代过程中删除元素:

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]

这个方法有一个严重的问题。当元素被移除,该列表的大小缩减,元素索引也随之发生了变化。所以,如果你想通过使用索引来删除一个循环内的多个元素,就会导致错误的结果。

你可能猜到可以使用iterator来删除循环中的元素。在Java中的foreach循环的工作原理就像一个iterator。 但是在这里也会发生错误。请看下面的代码:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
 
for (String s : list) {
	if (s.equals("a"))
		list.remove(s);
}

上面的foreach loop代码会抛出一个异常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();
	}
}

通过分析ArrayList.iterator()的原代码,我们可以发现next()方法必须要在remove()方法前被调用。在foreach loop中,编译器产生的代码会先调用next()方法,从而产生异常ConcurrentModificationException。请查看ArrayList.iterator()的原代码

#4. Hashtable 与 HashMap

按照算法惯例,Hashtable是数据结构的名称。但在Java中,数据结构的名称是HashMap。Hashtable是同步的版本。所以很多时候你并不需要Hashtable,而是HashMap。 这两篇文章详细介绍了各种Map的区别和常见的问题: HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMapMap常见10大问题,

#5.使用原始类型Collection

在Java中,原始类型和无界通配符类型很容易混在一起。以Set为例,Set是原始类型,而Set<?>是无界通配符类型。

考虑下面的代码,它使用原始类型的List作为参数:

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

此代码将抛出一个异常:

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

使用原始类型的Collection是危险的,因为原始类型的Collection跳过类型检查。另外值得一提的是Set, Set<?>, Set<Object>之间存在着巨大的差异。 了解更多,请查看原始类型 vs. 无界通配符类型 和 类型擦除

#6. 访问级别

很多时候,开发者使用public修饰字段。这样做的好处是很容易通过直接引用来获取字段的值,但是这是一个非常糟糕的设计。经验法则是“给成员的访问级别尽可能低”。可以查看Java4种不同的访问级别public, default, protected, and private

#7. ArrayList 与 LinkedList

当开发人员不知道ArrayList和LinkedList的区别的时候,他们经常使用的是ArrayList,可能因为它看起来面熟。但是ArrayList和LinkedList之间有巨大的性能差异。 简单来说如果有大量的添加/删除操作,而没有很多随机存取操作,LinkedList的应该是首选。可以查看ArrayList与LinkedList了解它们之间更多的区别。

#8.可变性与不变性

不可变对象有很多优点,如简单性,安全性等。但是它需要为每个不同的值创造一个单独的对象,对象太多可能会导致垃圾回收的成本高。所以可变和不可变之间进行选择时应该有一个平衡。

一般情况下,使用可变对象,以避免产生过多的中间对象。一个经典的例子是串联了大量的字符串。如果使用的是不可变的字符串String,会产生很多可以垃圾回收的对象。这样既浪费时间也浪费CPU的运算能力,使用可变对象是正确的解决方案(如StringBuilder)。

String result="";
for(String s: arr){
	result = result + s;
}

另外一些情况,可变对象刚更加合适可取。例如排序(Collections.sort())。如果Collection是不可变的,排序方法每次将会返回一个新的Collection,这样会极其浪费资源。 可以看看为什么在Java中String被设计成不可变?

#9. 父类和子类的构造函数

以上这段代码出现编译错误,因为默认的父类构造函数未定义。在Java中,如果一个类没有定义构造函数,编译器会默认插入一个默认的无参数构造函数。如果程序员定义构造函数,编译器将不插入默认的无参数构造函数。上面的代码由于自定义了有参数的构造函数,编译器不再插入无参数的构造函数。子类的构造函数,无论是有参数或无参数,都将调用父类无参构造函数。当子类需要父类的无参数构造函数的时候,就发生了错误。

解决这个问题,可以1)增加一个父类构造函数

public Super(){
    System.out.println("Super");
}

,或2)删除自定义的父类构造函数,或3)添加super(value)到子类构造函数。更多请查看父类和子类的构造函数

#10. "" 与 Constructor?

字符串可以通过两种方式创建:

//1. use double quotes
String x = "abc";
//2. use constructor
String y = new String("abc");

这两者有什么区别呢? 下面的例子可以提供一个快速的答案:

String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
 
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True

 

英文原文: Top 10 Mistakes Java Developers Make

16
2
分享到:
评论
11 楼 bitray 2014-06-02  
793059909 写道
检查数组是否包含一个值

开发人员经常做的是:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
这个代码是工作的,但没有没有效率。把列表转换成set没有必要,需要额外的时间。正确的方法是:

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


如果array中的重复值比较多,转换成set也未尝不可。
ArrayList的contains的时间复杂度是o(n),数据量越大,用的时间越长

o(n)还好。不是n2都能忍,哈
10 楼 793059909 2014-06-02  
xuhu_java 写道
第三条删除列表数据 这么玩也可以
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = (list.size() - 1); i >= 0; i--) {
     list.remove(i);
}
System.out.println(list);

关于这个问题相关资料整理:
http://www.cnblogs.com/softidea/p/3760213.html
9 楼 793059909 2014-06-02  
检查数组是否包含一个值

开发人员经常做的是:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
这个代码是工作的,但没有没有效率。把列表转换成set没有必要,需要额外的时间。正确的方法是:

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


如果array中的重复值比较多,转换成set也未尝不可。
ArrayList的contains的时间复杂度是o(n),数据量越大,用的时间越长
8 楼 jimmee 2014-06-01  
#2. 检查数组是否包含一个值


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

或者,一个简单的loop:

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

这种才是无效率的吧,想想数据量稍微大一点以后的遍历效率得有多差。。。。

想不到这种文章都能上iteye首页。。。
7 楼 mybreeze77 2014-05-31  
In the foreach loop, compiler will make the .next() called after the operation of removing element, which caused the ConcurrentModificationException.

在foreach loop中,编译器产生的代码会先调用next()方法,从而产生异常ConcurrentModificationException。

神翻译啊。。
6 楼 exceptionhelp 2014-05-31  
值得分享一下
5 楼 exceptionhelp 2014-05-31  
谢谢分享!
4 楼 yixiandave 2014-05-31  
第一个就中枪。。。
3 楼 alleni123 2014-05-30  
mark 一下。
2 楼 kuchaguangjie 2014-05-30  
good.
1 楼 xuhu_java 2014-05-30  
第三条删除列表数据 这么玩也可以
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = (list.size() - 1); i >= 0; i--) {
     list.remove(i);
}
System.out.println(list);

相关推荐

    Java程序员容易犯的10个错误

    本文将针对Java程序员容易犯的10个错误进行详细讲解,帮助大家避免这些陷阱。 1. **Array 转 ArrayList**: 当使用`Arrays.asList()`方法将数组转换为列表时,返回的是`java.util.Arrays.ArrayList`,这是一个内部...

    Java程序员们最常犯的10个错误

    ### Java程序员们最常犯的10个错误 #### 错误一:将数组错误地转化为列表 在Java中,很多程序员在尝试将数组转换为列表时,常常使用`Arrays.asList(arr)`这样的方法。虽然这种方法可以成功转换,但需要注意的是,`...

    Java程序员们最常犯的10个错误.docx

    本文将探讨Java程序员们最常犯的10个错误,并给出相应的纠正方法,这对于准备Java面试或者日常开发工作都是十分有价值的。 1. **数组转换为列表的错误**: 当我们需要将数组转换为列表时,很多人会直接使用`Arrays...

    Java 程序员在写 SQL 时常犯的 10 个错误

    以下是根据标题和描述中提到的几点,对Java程序员在SQL编程中常犯错误的详细解析: 1. 忽视NULL的特殊性 NULL在SQL中的含义是未知,与Java中的null不同。Java程序员经常混淆这两个概念,尤其是在使用NULL作为比较...

    Java程序员在写SQL程序时候常犯的10个错误_.docx

    Java程序员在编写SQL程序时,由于SQL语言的特性和与Java的差异,常常会遇到一些常见错误。以下是对这些错误的详细分析和解决方案: 1. 忘记处理NULL值 NULL在SQL中的处理方式与Java中不同,容易引发混淆。Java中的...

    Java程序员常犯的五个错误

    以下是Java程序员常犯的五个错误的详细解析,以及如何避免这些错误的建议。 1. **过度使用 null** 在Java中,null 常常被用来表示“无”或“不存在”,但过度依赖null可能导致NullPointerException。当方法返回...

    java常犯的错误

    介绍了java程序员在写程序的时候容易犯的10种错误

    Java程序员容易犯的10大低级错误

    "Java程序员容易犯的10大低级错误" 本文总结了Java程序员容易犯的10大低级错误,旨在帮助开发人员避免这些...这10个错误都是Java程序员容易犯的低级错误。通过了解这些错误,开发人员可以避免这些错误,提高编程质量。

    全世界所有程序员都会犯的错误

    标题“全世界所有程序员都会犯的错误”暗示了这是一篇面向广大程序员的文章,旨在揭示在编程过程中容易出现的普遍性错误。这种错误具有广泛的适用性和警示意义,对于提高编程质量、减少bug有重要的参考价值。 #### ...

    JAVA程序员必需搞懂的问题

    JAVA程序员必需搞懂的问题,描述一些Java程序员需注意的问题一些容易犯的错误。

    Java 程序员容易犯的10个SQL错误

    【Java程序员容易犯的10个SQL错误】这篇文章聚焦于Java开发者在编写SQL语句时常见的误区,这些错误可能导致程序的不稳定或者效率低下。以下是详细分析: 1. **忽视NULL的特殊性**:Java程序员经常对SQL中的NULL值...

    JAVA程序员必读基础篇

    JAVA是有SUN公司开发的新一代编程语言,它可以用在各种不同的机器、操作系统的网络环境中...所以作为Internet应用的开发技术人员不可不看JAVA,而JAVA程序不可不先从基础学起,这正是JAVA程序员必读:基础篇的用意。

    java面试笔试资料Java经典项目集锦java笔试题大集合及答案题库java笔试题汇总资料个合集(188).zip

    Java程序员们最常犯的10个错误.docx java程序员的就业指导(重点).docx Java程序员面试宝典 .pdf java笔试题大集合及答案 Java经典项目集锦.rar JAVA编程题全集(100题及答案).doc Java面试文档题库 Java面试笔试题库....

    java面试笔试题库java笔试题大集合及答案互联网公司面试资料Java面试问题集大全合集(200个).zip

    Java程序员们最常犯的10个错误.docx java程序员的就业指导(重点).docx Java程序员面试宝典 .pdf java笔试题大集合及答案 Java经典项目集锦.rar JAVA编程题全集(100题及答案).doc java面试书籍源码 Java面试笔试题库....

    java程序员常见的sql错误

    然而,许多 Java 程序员在编写 SQL 语句时经常犯的一些错误。这些错误可能会导致程序的性能下降、数据的损失或安全漏洞。 错误 1: 不使用批量更新 在编写 SQL 语句时,Java 程序员最常见和最大的一个错误就是忘记...

    java易犯错误.pdf

    ### Java易犯错误知识点概述 #### 一、何时被覆盖的方法实际上并未被真正覆盖 Java是一种面向对象的编程语言,其三大核心概念分别是封装、继承和多态。在这三个概念中,多态尤为关键,而多态的一个重要体现就是...

    写Java程序最容易犯的错误例析

    ### 写Java程序最容易犯的错误例析 在软件开发过程中,编写高质量的代码是非常重要的。良好的代码不仅能提高系统的可维护性和可扩展性,还能减少未来的维护成本。本文将详细介绍编写Java程序时最常见的21个错误,并...

    Java程序最容易犯的21种错误

    【Java程序最容易犯的21种错误】是一个关于Java编程中常见问题的总结,这些问题可能导致代码质量下降,可维护性和可扩展性降低。以下是对这些错误的详细解释: 1. **重复代码(Duplicated Code)**:代码重复是降低...

    java面试笔试资料java笔试题大集合及答案题库java笔试题汇总资料188个合集.zip

    Java程序员们最常犯的10个错误.docx java程序员的就业指导(重点).docx Java程序员面试宝典 .pdf java笔试题大集合及答案 Java经典项目集锦.rar JAVA编程题全集(100题及答案).doc Java面试文档题库 Java面试笔试题库....

Global site tag (gtag.js) - Google Analytics