Java基础入门-JAVA的集合类

来源:互联网 发布:js input 只读属性 编辑:程序博客网 时间:2024/06/08 04:04
集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类存放于java.util包中。
集合类型主要有3种:set(集)、list(列表)和map(映射)。

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
└HashMap



Collection 接口

  Collection是最基本的集合接口;一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。

       Collection接口是 Set 和List  接口的父接口,由Collection接口派生的两个接口是List和Set。

Collection接口提供了多数集合常用的方法声明:

add(E e)将指定对象添加到集合中remove(Object o)将指定的对象从集合中移除,移除成功返回true,不成功返回falsecontains(Object o)查看该集合中是否包含指定的对象,包含返回true,不包含返回flasesize()返回集合中存放的对象的个数。返回值为intclear()移除该集合中的所有对象,清空该集合。iterator()返回一个包含所有对象的iterator对象,用来循环遍历toArray()返回一个包含所有对象的数组,类型是ObjecttoArray(T[] t)返回一个包含所有对象的指定类型的数组
下面是集合转成数组的例子,因为Collection本身是个接口所以,可以用它的实现类ArrayList来实现:

import java.util.ArrayList;02import java.util.Collection;03 04public class DemoTest {05 06    public static void main(String[] args) {07 08        String a = "a",b="b",c="c";09        Collection cList = new ArrayList();10        cList.add(a);11        cList.add(b);12        cList.add(c);13 14        String[] strArray =  list.toArray(new String[1]);15 16        for(String s : strArray){17            System.out.println(s);18        }19    }20}

  遍历Collection中的每一个元素

不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
    Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元素
    }
  

List接口
  List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置,List允许有相同的元素。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
  实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

LinkedList类
  LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。
  注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));

(在网上查找的,平时用的不多,主要是ArrayList)

ArrayList类
  ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
  每个ArrayList实例都有一个用于存储元素的数组的大小。这个大小可随着不断添加新元素而自动增加,但是增长算法 并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity()方法来增加ArrayList的容量以提高插入效率。

ArrayList是一个可变长的数组实现,读取效率很高,是最常用的集合类型。

1、ArrayList的创建

List<String> list = new ArrayList<String>();

上面的代码定义了一个只允许保存字符串的列表,尖括号括住的类型就是参数类型,也成泛型。带泛型的写法给了我们一个类型安全的集合。关于泛型的知识可以参见这里。

2、ArrayList的使用:

01 List<String> list = new ArrayList<String>();
02 list.add("1");
03 list.add("2");
04 list.add("3");
05 list.add("4");
06 list.add("5");
07 System.out.println(list.size());
08 System.out.println(list.contains(21));
09 System.out.println(list.remove("3"));
10 System.out.println(list.size());

关于List接口中的方法和ArrayList中的方法,大家可以看看JDK中的帮助。

3、基本数据类型的的自动装箱:

我们知道集合中存放的是对象,而不能是基本数据类型,在Java5之后可以使用自动装箱功能,更方便的导入基本数据类型。

1 List<Integer> list = new ArrayList<Integer>();
2 list.add(new Integer(42));
3 list.add(43);

4、数组和List之间的转换

从数组转换成list,可以使用Arrays类的asList()方法:

01 import java.util.ArrayList;
02 import java.util.Collections;
03 import java.util.List;
04  
05 public class Demo2 {
06  
07    public static void main(String[] args) {
08  
09            String[] sa = {"1","2","3","4"};
10            List list = Arrays.asList(sa);
11            System.out.println("list:"+list);
12            System.out.println("list.size()="+list.size());
13    }
14  
15 }

5、Iterator和for-each

在for-each出现之前,我们想遍历ArrayList中的每个元素我们会使用Iterator接口:

01 import java.util.Arrays;
02 import java.util.Iterator;
03 import java.util.List;
04  
05 public class Test1 {
06  
07    public static void main(String[] args) {
08  
09        // Arrays类为我们提供了一种list的便捷创建方式
10        List<String> list = Arrays.asList("1", "2", "3", "4");
11  
12        // 转换成Iterator实例
13        Iterator<String> it = list.iterator();
14  
15        //遍历
16        while (it.hasNext()) {
17            System.out.println(it.next());
18        }
19  
20    }
21  
22 }

在for-each出现之后,遍历变得简单一些:

01 import java.util.Arrays;
02 import java.util.Iterator;
03 import java.util.List;
04  
05 public class Test2 {
06  
07    public static void main(String[] args) {
08  
09        // Arrays类为我们提供了一种list的便捷创建方式
10        List<String> list = Arrays.asList("1", "2", "3", "4");
11  
12        for (String s : list) {
13            System.out.println(s);
14        }
15  
16    }
17  
18 }

Vector类
  Vector 是ArrayList的线程安全版本,性能比ArrayList要低,现在已经很少使用

Stack 类
  Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。 (在网上查找的,现在很少用到Vector类和Statck类)

Set接口
  Set是一种不包含重复的元素的Collection,
即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
  请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

Map接口
  请注意,Map没有继承Collection接口,Map提供key到value的映射,以键值对的形式cunz。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

Map接口的常用方法如下表所示:

put(K key, V value)向集合中添加指定的键值对putAll(Map <? extends K,? extends V> t)把一个Map中的所有键值对添加到该集合containsKey(Object key)如果包含该键,则返回truecontainsValue(Object value)如果包含该值,则返回trueget(Object key)根据键,返回相应的值对象keySet()将该集合中的所有键以Set集合形式返回values()将该集合中所有的值以Collection形式返回remove(Object key)如果存在指定的键,则移除该键值对,返回键所对应的值,如果不存在则返回nullclear()移除Map中的所有键值对,或者说就是清空集合isEmpty()查看Map中是否存在键值对size()查看集合中包含键值对的个数,返回int类型

Hashtable类
 注意Hashtable中的t是小写的,它是HashMap的线程安全版本,现在已经很少使用。

HashMap类
  HashMap和Hashtable类似,不同之处在于HashMap是非同步的,注意Hashtable中的t是小写的,它是HashMap的线程安全版本,现在已经很少使用。并且允许null,即null value和null key。


相互区别(网上查找)

Vector和ArrayList

1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用

arraylist效率比较高。
2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度

的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而

如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据

所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。

ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要 差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

arraylist和linkedlist

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
    这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数 据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。


HashMap与TreeMap
        (注)
       文章出处:http://www.diybl.com/course/3_program/java/javaxl/200875/130233.html

       1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

HashMap中元素的排列顺序是不固定的)。

        2、  HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该 使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。

         3、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。  这个TreeMap没有调优选项,因为该树总处于平衡状态。

      结过研究,在原作者的基础上我还发现了一点,二树map一样,但顺序不一样,导致hashCode()不一样。
      同样做测试:
      在hashMap中,同样的值的map,顺序不同,equals时,false;
      而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。

hashtable与hashmap

一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现

二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

三.值:只有HashMap可以让你将空值作为一个表的条目的key或value


1 0
原创粉丝点击