此文转载自: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. js 冒泡事件阻止 父层事件影响子层

    当父层 与子层 有相同的事件时,但子层跟父层执行的内容却不一样时 为了 防止 父层事件对子层造成影响我们可以在子层的方法里做如下操作 function A (event){ event.stopPro ...

  2. DevExpress WinForms使用教程:Diagram Control

    [DevExpress WinForms v18.2下载] DevExpress WinForms v18.2包含WinForms和WPF Diagram Controls的三个高要求功能:新的Dia ...

  3. k8s weave network IP回收冲突

    问题:将备用集群的一个机器加入到新的集群中的时候,出现该机器上的pod都不能被访问. 查明原因是weave 没有删除干净 https://github.com/weaveworks/weave/iss ...

  4. Entity Framework数据库初始化

    public class ApplicationContext : DbContext { public DbSet<User> Users { get; set; } public Ap ...

  5. [深入理解Java虚拟机]<垃圾收集器与内存分配策略>

    Overview 垃圾收集考虑三件事: 哪些内存需要回收? 什么时候回收? 如何回收? 重点考虑Java堆中动态分配和回收的内存. Is Object alive? 引用计数法 给对象添加一个引用计数 ...

  6. 全局css , 样式设置, css 初始化. css ,style ,全局样式, 初始化样式

    全局CSS设置总结 1.清除所有标记的内外边距 html, body, ul, li, ol, dl, dd, dt, p, h1, h2, h3, h4, h5, h6, form, fieldse ...

  7. The databse returned no natively generated identity value问题

    com.cqupt.dayday.model 代码 package com.cqupt.dayday.model; import java.util.Date; /** * Created by I ...

  8. [python]操作redis sentinel以及cluster

    先了解清楚sentinel和cluster的差别,再学习使用python操作redis的API,感觉会更加清晰明白. 1.redis sentinel和cluster的区别 sentinel遵循主从结 ...

  9. Python学习笔记第十二周

    目录: 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令事务 索引 创建数据库 外键 增删改查表 权限 python 操作mysql  ORM sqla ...

  10. JavaScript事件基础-10-2.HTML事件; DOM0级事件; 掌握常用的鼠标与键盘事件 ; 掌握this的指向;

    JavaScript事件基础 学习目标 1.掌握什么是事件 2.掌握HTML事件 3.掌握DOM0级事件 4.掌握常用的鼠标与键盘事件 5.掌握this的指向 什么是事件 事件就是文档或浏览器窗口中发 ...