Java程序员们最常犯的3个集合错误

标签: java java基础知识 | 发表时间:2015-09-29 11:28 | 作者:一名清官
出处:http://www.javaranger.com

1.将数组转化为列表
将数组转化为一个列表时,程序员们经常这样做:

List list = Arrays.asList(arr);

Arrays.asList() 会返回一个ArrayList对象,ArrayList类是Arrays的一个私有静态类,而不是java.util.ArrayList 类,java.util.Arrays.ArrayList类有set()、get()、contains()方法,但是没有增加元素的方法,所以它的大 小是固定的,想要创建一个真正的ArrayList类,你应该这样做:

ArrayList arrayList = new ArrayList(Arrays.asList(arr));

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

2.判断一个数组是否包含一个值
程序员们经常这样做:

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

这段代码起作用,但是没有必要把一个数组转化成列表,转化为列表需要额外的时间。它可以像下面那样简单:

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

或者是:

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

很显然第一种方法比第二种更容易读
3.在一个循环中删除一个列表中的元素
思考下面这一段在循环中删除多个元素的的代码:

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

它会抛出一个ConcurrentModificationException异常。
相反下面的显示正常:

ArrayList list = new ArrayList(Arrays.asList("a", "b","c", "d"));
    Iterator iter = list.iterator();
    while (iter.hasNext()) {
        String s = iter.next();
        if (s.equals("a")) {
            iter.remove();
         }
    }

.next() 必须在.remove()之前调用。在一个foreach循环中,编译器会使.next()在删除元素之后被调用,因此就会抛出 ConcurrentModificationException异常,你也许希望看一下ArrayList.iterator()的源代码。

相关 [java 程序员 集合] 推荐:

Java程序员们最常犯的3个集合错误

- - JavaRanger - 专注JAVA高性能程序开发、JVM、Mysql优化、算法
将数组转化为一个列表时,程序员们经常这样做:. Arrays.asList() 会返回一个ArrayList对象,ArrayList类是Arrays的一个私有静态类,而不是java.util.ArrayList 类,java.util.Arrays.ArrayList类有set()、get()、contains()方法,但是没有增加元素的方法,所以它的大 小是固定的,想要创建一个真正的ArrayList类,你应该这样做:.

Java程序员常用工具集

- - BlogJava-庄周梦蝶
    我发现很多人没办法高效地解决问题的关键原因是不熟悉工具,不熟悉工具也还罢了,甚至还不知道怎么去找工具,这个问题就大条了. 我想列下我能想到的一个Java程序员会用到的常用工具. 1.IDE: Eclipse或者 IDEA,熟悉尽可能多的快捷键,《 Eclipse常见快捷键列表》. (1) Findbugs,在release之前进行一次静态代码检查是必须的.

Java系统程序员修炼之道

- - 博客 - 伯乐在线
从2002开始接触Java学会HelloWorld这么经典的程序到如今不知不觉已经十年啦,十年中亲耳听到过不少大牛的演讲,见到过项目中的神人在键盘上运指如飞的编程速度,当时就被震撼了. 当编程越来越成体力活,我们还能有自己的思想,还能修炼为Java系统级别的 程序员嘛. 学习与修炼以下知识与技能,帮你早日达成愿望.

Java程序员的现代RPC指南

- - CSDN博客推荐文章
Java程序员的现代RPC指南. 最早接触RPC还是初学Java时,直接用Socket API传东西好麻烦. 于是发现了JDK直接支持的RMI,然后就用得不亦乐乎,各种大作业里凡是涉及到分布式通信的都用RMI,真是方便. 后来用上了Spring,发现Spring提供了好多Exporter,可以无侵入地将一个POJO暴露为RPC服务.

Java 集合类学习

- - CSDN博客推荐文章
二、 几个比较重要的接口和类简介. 1、List(有序、索引、可重复).      List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法.      ArrayList(数组、快速访问).      ArrayList可以理解成一个可增长的数组,因此可以通过索引快速访问.

JAVA集合分析概述

- - ITeye博客
       前段时间在QQ空间写了篇关于JAVA集合分析的日志,现搬到这里与大家分享. 其中有链接可查看各种集合的具体介绍.  最基本的数据结构有数组、链表2种.         1)数组的长度是固定的,容量是有限的(除非扩容). 可以用索引访问,因此访问速度比较快.         2)链表中每个节点指向下一个节点,容量是无限的(不作限制且不考虑硬件).

Java面试题:多线程,作为Java程序员你不得不懂

- sun - IT程序员面试网
线程:是指进程中的一个执行流程. 线程与进程的区别:每个进程都需要操作系统为其分配独立的内存地址空间,而同一进程中的所有线程在同一块地址空间中工作,这些线程可以共享同一块内存和系统资源. 创建线程有两种方式,如下: 1、 扩展java.lang.Thread类 2、 实现Runnable接口 Thread类代表线程类,它的两个最主要的方法是: run()——包含线程运行时所执行的代码 Start()——用于启动线程.

Java程序员不该有的6种陋习

- - BlogJava-首页技术区
只有在学会处理异常之后,我们才能说自己是一个合格的java程序员. 只有在摆脱了以下六种异常处理的陋习之后,才能威慑一下刚毕业的小菜鸟.   现在就来测试一下大家对异常的掌握程度. 不用担心,事实上,这些不合理的设计很容易看出来. 那么,以下六种不合理的代码,大家能看出每一种的问题出在哪儿吗.   + ",姓名:" + rs.getString("name"));.

25个让Java程序员更高效的Eclipse插件

- - 博客 - 伯乐在线
Eclipse提供了一个可扩展插件的开发系统. 这就使得Eclipse在运行系统之上可以实现各种功能. 这些插件也不同于其他的应用(插件的功能是最难用代码实现的). 拥有合适的Eclipse插件是非常重要的,因为它们能让Java开发者们无缝的开发基于J2EE和服务的应用程序. Eclipse的插件也能帮助他们开发不同应用架构上的程序.

java程序员必知的8大排序

- - CSDN博客推荐文章
   (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排. 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数. 如此反复循环,直到全部排好顺序. //将大于temp的值整体后移一个单位. 2,           希尔排序(最小增量排序). (1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序.