shocked! Java programmers turned out to be the most common mistakes are that 10

And the vast majority of programmers, I am also very house. A luxury that most weekend stroll around technology-based Web site, for example programcreek, there are some very interesting topics on this small site. For example: Java programmers turned out to be the most common mistakes are that 10, it is like a kind of curiosity killed the cat would like the theme of, well worth picking out to share with you.

PS: Do not ask me , "Why do you want to add the title 'shocked'?" Asked the answer is only one - to scare people - gotta tap into people's interest in reading thing (I easily do I).

01, turn into the Array ArrayList

Indeed, many Java programmers like to turn into Array ArrayList:

List<String> list = Arrays.asList(arr);
复制代码

But in fact, Arrays.asList()it returned ArrayList is not java.util.ArrayList, but Arrays internal private class java.util.Arrays.ArrayList. Though the exact same name, are ArrayListbut two very different classes. Arrays.ArrayListAlthough there are set(), get()and contains()the like, but not a method for adding an element, so its size is fixed.

If you want to create a real ArrayListneed to do so:

List<String> list = new ArrayList<String>(Arrays.asList(arr));
复制代码

ArrayListConstructor Collection may receive one type of parameter and Arrays.ArrayListits subclasses, such can be converted.

02, by checking Set the array contains a value

Before I wrote an article " How to Check Java array contains a value " was mentioned method:

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

This method does work, but it ignores the performance problems; to be able to complete the inspection as soon as possible, you can do this:

Arrays.asList(arr).contains(targetValue);
复制代码

Common for loop or use or for-each.

03, elements in the list by deleting the for loop

Novice special columns prefer to use a for loop to delete elements in the list, like this:

List<String> list = new ArrayList<String>(Arrays.asList("沉""默""王""二"));
for (int i = 0; i < list.size(); i++) {
    list.remove(i);
}
System.out.println(list);
复制代码

The purpose of the above code is deleted all elements of the list, but the result of it:

[默, 二]
复制代码

竟然还有两个元素没删除,why?

当 List 的元素被删除时,其 size() 会减小,元素的下标也会改变,所以想通过 for 循环删除元素是行不通的。

那 for-each 呢?

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

System.out.println(list);
复制代码

竟然还抛出异常了:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    at java.util.ArrayList$Itr.next(ArrayList.java:859)
    at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:15)
复制代码

抛出异常的原因,可以查看我之前写的文章《Java,你告诉我 fail-fast 是什么鬼?》。

有经验的程序员应该已经知道答案了,使用 Iterator:

Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();

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

System.out.println(list);
复制代码

程序输出的结果如下:

[默, 王, 二]
复制代码

04、使用 Hashtable 而不是 HashMap

通常来说,哈希表应该是 Hashtable,但在 Java 中,哈希表通常指的是 HashMap。两者之间的区别之一是 Hashtable 是线程安全的。如果没有特殊要求的话,哈希表应该使用 HashMap 而不是 Hashtable。

05、使用原始类型

在 Java 中,新手很容易混淆无限通配符和原始类型之间的差别。举例来说,List<?> list 为无限通配符,List 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, 18);
    add(list, "沉默王二");
    String s = list.get(0);
}
复制代码

这段代码在运行时会抛出异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:38)
复制代码

使用原始类型非常的危险,因为跳过了泛型的检查。至于 List<Object>List 之间的区别,查看我写的另外一篇文章:《为什么不应该使用Java的原始类型》。

06、使用 public 修饰字段

有些新手喜欢使用 public 修饰字段,因为不需要 getter/setter 方法就可以访问字段。但实际上,这是一个非常糟糕的设计;有经验的程序员更习惯于提供尽可能低的访问级别。

07、使用 ArrayList 而不是 LinkedList

新手往往搞不清楚 ArrayList 和 LinkedList 之间的区别,因此更倾向于使用 ArrayList,因为比较面熟。但是呢,它们之间存在巨大的性能差异。简单的说吧,如果“添加/删除”的操作比较多,而“获取”的操作比较少,则应该首选 LinkedList。

08、使用过多的不可变对象

不可变对象有着不少的优点,比如说简单性和安全性。但是呢,如你所料,它也有一些难以抗拒的弊端:对于每一个不同的值,它都需要一个单独的对象来表示,这样的对象太多的话,很可能会导致大量的垃圾,回收的成本就变得特别高。

为了在可变与不可变之间保持平衡,通常会使用可变对象来避免产生太多中间对象。一个经典的例子就是使用 StringBuilder(可变对象) 来连接大量的字符串,否则的话,String(不可变对象)会产生很多要回收的垃圾。

反例:

String result="";
for(String s: arr){
    result = result + s;
}
复制代码

正例:

StringBuilder result = new StringBuilder();
for (String s: strs) {
    result.append(s);
}
复制代码

参考文章:为什么 Java 字符串是不可变的?

09、父类没有默认的无参构造方法

在 Java 中,如果父类没有定义构造方法,则编译器会默认插入一个无参的构造方法;但如果在父类中定义了构造方法,则编译器不会再插入无参构造方法。所以下面的代码会在编译时出错。

子类中的无参构造方法试图调用父类的无参构造方法,但父类中并未定义,因此编译出错了。解决方案就是在父类中定义无参构造方法。

10、使用构造方法创建字符串

创建字符串有两种方法:

1)使用双引号

String er = "沉默王二";
复制代码

2)使用构造方法

String san = new String("沉默王三");
复制代码

但是它们之间有着很大的不同(可以参照创建 Java 字符串,用""还是构造函数),双引号被称为字符串常量,可以避免重复内容的字符串在内存中创建。

好了,读者朋友们,以上就是本文的全部内容了。可以掏心窝子地说,没有任何客观的数据来证明它们就是前十名,但绝对非常普遍。如果不认可其中的内容,请在留言区轻喷,好人有好报。如果觉得不过瘾,还想看到更多,可以 star 二哥的 GitHub【itwanger.github.io】,本文已收录。

原创不易,如果觉得有点用的话,请不要吝啬你手中点赞的权力——这将是我最强的写作动力;如果想要第一时间看到二哥更新的文章,请扫描下方的二维码,关注【沉默王二】公众号。我们下篇文章见!

Guess you like

Origin juejin.im/post/5e13d24cf265da5d45542608