此文转载自:http://student-lp.iteye.com/blog/2082362

在java编程的过程中,我们不能确定某一类型的对象到底会需要多少,为了解决这个问题,java提供了容纳对象的多种方式。其中内建的类型是数组;此外还提供了“集合类”,利用这些集合类,我们就可以容纳并操作自己的对象。

一、数组

如何区分数组和其他集合类呢?其实有两种方式可以区分开:效率和类型。在java中,数组是一个简单的先行序列,它使得元素的访问速度非常快,但付出的代价是--创建一个数组对象时,他的大小是固定的,而且不可在那个数组对象的“存在时间”内发生改变(也就是只能容纳一种类型的对象)。

有关数组越界问题?在java中,无论使用的是数组还是集合,都会进行范围检查---若超过边界,就会获得一个RuntimeException错误。

数组的初始化,我们在创建一个数组后,自动进行了初始化,初始化值为null。而对应基本类型的数组,会自动初始化为零(数值类型),null(字符类型)或者FALSE(布尔类型)。

二、集合

1、早期集合类型

在早期java提供了四种类型的“集合类”:Vector(适量)、BitSet(位集)、Stack(堆栈)以及Hashtable(散列表)。在使用这些java集合时会发现一个缺点,就是:将一个对象置入一个集合时会丢失类型信息。之所以发生这种情况,是由于当初编写集合时,那个集合的程序员根本不知道用户到底想把什么类型的置入到集合中。为了解决这个问题,集合实际容纳的类型为object。这些早期类型已经不太常用,所以这里不再细讲。下面我们主要了解一下新集合。

2、新集合

1) 新的集合库考虑了“容纳自己对象”的问题,并将其分割成两个明确的概念:

①集合(Collection):一组单独的元素,通常应用了某种规则。在这里,List(列表)区分元素的顺序,且允许出现重复的值;Set(集)不区分元素的顺序,不允许出现重复的值;

②映射(Map):一系列“键--值”对。不允许有重复的键,每个键最多对应一个值。

Collection和Map可以通过多种形式实现,下面列出的是一个可以帮助大家立即的集合示意图:


总的说来,Java API中所用的集合类,都是实现了Collection接口,他的一个类继承结构如下:

Collection<--List<--Vector
                  Collection<--List<--ArrayList
                  Collection<--List<--LinkedList
                  Collection<--Set<--HashSet
                  Collection<--Set<--HashSet<--LinkedHashSet
                  Collection<--Set<--SortedSet<--TreeSet

2)list常用的衍生类

Vector : 基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能不受Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就是Vector:sychronized(线程安全)的,这个也是Vector和ArrayList的唯一的区别。

ArrayList:同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。

LinkedList:LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这就是LinkedList的优势。

总结:1. 所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对;

2. 所有的List中可以有相同的元素,例如ArrayLIst中可以有 [ tom,koo,too,koo ];

3. 所有的List中可以有null元素,例如[ tom,null,1 ];

4. 基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。

3)set常用的衍生类

HashSet:HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。看看HashSet的add(Object  obj)方法的实现就可以一目了然了。
    public boolean add(Object obj)
    {
        return map.put(obj, PRESENT) == null;
    }

这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。

LinkedHashSet:HashSet的一个子类,一个链表。

TreeSet:SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。

总结:1. Set实现的基础是Map(HashMap);

2.  Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

3)list和set却别

虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在HashMap的基础上来实现的,这个就是Set和List的根本区别。

4)映射

HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。并且Hashtable是同步的

HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个),即null value和null key。HashMap是非同步的。

WeakHashMap:WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。

TreeMap: 实现这样一个映象,对象是按键升序排列的。

5)同步性

①Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。而ArrayList则是异步的,因此ArrayList中的对象并 不是线程安全的。因为同步的要求会影响执行的效率,所以如果你不需要线程安全的集合那么使用ArrayList是一个很好的选择,这样可以避免由于同步带 来的不必要的性能开销。

②Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

6)常见的对比

①Vector和ArrayList:参见5)同步性①

②arraylist和linkedlist:ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构;对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针;对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据;

③HashMap与TreeMap:TreeMap是有序的,而HashMap是无序存储的;在Map 中插入、删除和定位元素,HashMap 的效率要更高一些;

④hashtable与hashmap:参见5)同步性②

三、Collections和Arrays类的使用

1、Collections定义了多种集合操作的方法,实现对集合元素排序,取极值,批是拷贝,集合结构转换,循环移位以及匹配检查等功能

相关方法:
           sort(List<T> list)  根据元素的自然顺序 对指定列表按升序进行排序。
           reverse(List<?> list)  反转指定列表中元素的顺序。
           shuffle(List<?> list)  使用默认随机源对指定列表进行置换。
           copy(List<? super T> dest, List<? extends T> src) 将所有元素从一个列表复制到另一个列表。
           list(Enumeration<T> e) 返回一个数组列表,它按返回顺序包含指定枚举返回的元素
           frequency(Collection<?> c, Object o) 返回指定 collection 中等于指定对象的元素数
           max(Collection<? extends T> coll)  根据指定比较器产生的顺序,返回给定 collection 的最大元素
           rotate(List<?> list, int distance) 根据指定的距离轮换指定列表中的元素。

      在Collections中还有一个非常重要的作用,就是synchronizedXXX(new XXX)。 Collections类为集合类们提供的同步控制方法


2、Arrays类定义了多种数组操作方法,实现了对数组元素 排序,填充,转换为列表或字符串形式、增强的检索和深度比较等功能

              asList()返回一个受指定数组支持的固定大小的列表
              sort()对指定的 byte 型数组按数字升序进行排序
              binarySearch(int[] a, int key) 使用二分搜索法来搜索指定的 int 型数组,以获得指定的值。
              toString(Object[] a)  返回指定数组内容的字符串表示形式。

Java中的数组与集合的更多相关文章

  1. java中的数组与集合相互转换

    1.数组转换成集合 数组转换为集合,用Arrays.asList方法. public static void main(String[] args) { String[] arr = {"a ...

  2. Java比较器对数组,集合排序一

    数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...

  3. 【JAVA零基础入门系列】Day10 Java中的数组

    什么是数组?顾名思义,就是数据的组合,把一些相同类型的数放到一组里去. 那为什么要用数组呢?比如需要统计全班同学的成绩的时候,如果给班上50个同学的成绩信息都命名一个变量进行存储,显然不方便,而且在做 ...

  4. 第81节:Java中的数组

    第81节:Java中的数组 本节介绍数组的基本概念,数据就是一种数据结构,可以用来存储多个数据,每个数组中可以存放相同类型的数据.比如,在学校,我们是一个班,这里的班级中每个同学都是这个班级数组中的元 ...

  5. Java学习之路(三):Java中的数组

    数组的概述和定义的格式 数组的作用: 用来存储同种数据类型的多个值 数组的基本概念: 数组是存储同一种数据类型多个元素的集合.就相当于一个容器. 注意:数组既可以存储基本数据类型,也可以存储引用数据类 ...

  6. Java中的数组和方法

    3.1 数组的定义和使用 数组(Array)是用来存储一组相同数据类型数据的集合.数组中的每个数据称为一个元素(element),数组可以分为一维数组,二维数组和多维数组.我们 主要讲解一维数组和二维 ...

  7. java中一个数组不能放不同数据类型的值

    在java中,数组不能放不同数据类型的值. 方法一: 多态 定义数组类型的时候定义为父类,而存进数组为父类的子类 public class test2 { public static void mai ...

  8. Java中的容器(集合)之ArrayList源码解析

    1.ArrayList源码解析 源码解析: 如下源码来自JDK8(如需查看ArrayList扩容源码解析请跳转至<Java中的容器(集合)>第十条):. package java.util ...

  9. Java中的容器(集合)之HashMap源码解析

    1.HashMap源码解析(JDK8) 基础原理: 对比上一篇<Java中的容器(集合)之ArrayList源码解析>而言,本篇只解析HashMap常用的核心方法的源码. HashMap是 ...

随机推荐

  1. web项目与jsp有关的三个jar的依赖

    <!-- jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId> ...

  2. input获取焦点无效

    js控制input获得焦点: $("input").focus(); 无效,写在延时函数中问题解决: setTimeout(function(){ $("input&qu ...

  3. nginx 隐藏nginx版本号

    为什么要隐藏 Nginx 版本号:一般来说,软件的漏洞都与版本有关,隐藏版本号是为了防止恶意用户利用软件漏洞进行攻击 worker_processes 1; events { worker_conne ...

  4. 如何实时查看Linux下日志

    以下以Tomcat为例子,其他WEB服务器目录自己灵活修改即可: 1.先切换到:cd usr/local/tomcat5/logs2.tail -f catalina.out3.这样运行时就可以实时查 ...

  5. python分析nginx自定义日志

    # -*- coding:utf-8 -*- import datetimeimport re logfile = '''192.168.23.43 - 2017-12-14:00:14:41 /se ...

  6. 2019-04-03-day025-异常与日志

    内容回顾 考试 6个小时 120分 (100+20) 15:00-18:00 笔试 60分 19:00-22:00 上机考试 40分 + 20分 60分及格不算附加题 简答题 读程序 简单编程 编程题 ...

  7. Python基础6--函数、类和文件操作

    1 def name(para) def myabs(x): if x>0: return x else: return -x 2 lambda表达式 用于声明匿名函数,既没有名字的小函数 f ...

  8. git之自学

  9. Spring架构-01-微服务架构

    一.单体架构 所有功能,所有模块都耦合在一个系统里面,如传统的一MVC. 需要重新编译测试,重新部署. 伸缩性差 可靠性差 系统迭代困难 跨开发语言程序低 团队协作麻烦 二.微服务架构 常见架构风格: ...

  10. php 怎样将有范围的ip转化为整型范围

    php中将IP转换成整型的函数ip2long()容易出现问题,在IP比较大的情况下,会变成负数.如下: <?php $ip = "192.168.1.2"; $ip_n = ...