Java基础入门-JAVA的集合类

集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。

集合类存放于java.util包中。

集合类型主要有3种:set(集)、list(列表)和map(映射)。

 

 

 

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,不成功返回false
contains(Object o)查看该集合中是否包含指定的对象,包含返回true,不包含返回flase
size()返回集合中存放的对象的个数。返回值为int
clear()移除该集合中的所有对象,清空该集合。
iterator()返回一个包含所有对象的iterator对象,用来循环遍历
toArray()返回一个包含所有对象的数组,类型是Object
toArray(T[] t)返回一个包含所有对象的指定类型的数组

下面是集合转成数组的例子,因为Collection本身是个接口所以,可以用它的实现类ArrayList来实现:

import java.util.ArrayList;
import java.util.Collection;
	 
public class DemoTest {
	 
	public static void main(String[] args) {
	 
	    String a = "a",b="b",c="c";
	    Collection cList = new ArrayList();
	    cList.add(a);
	    cList.add(b);
	    cList.add(c);
	 
	    String[] strArray =  list.toArray(new String[1]);
	 
	    for(String s : strArray){
	        System.out.println(s);
	    }
	}
}

遍历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的使用:

 List<String> list = new ArrayList<String>();
 list.add("1");
 list.add("2");
 list.add("3");
 list.add("4");
 list.add("5");
 System.out.println(list.size());
 System.out.println(list.contains(21));
 System.out.println(list.remove("3"));
 System.out.println(list.size());

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

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

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

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

4、数组和List之间的转换

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
public class Demo2 {
   public static void main(String[] args) {
           String[] sa = {"1","2","3","4"};
           List list = Arrays.asList(sa);
           System.out.println("list:"+list);
           System.out.println("list.size()="+list.size());
   }
}

5、Iterator和for-each

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

 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
  
 public class Test1 {  
    public static void main(String[] args) {  
        // Arrays类为我们提供了一种list的便捷创建方式
        List<String> list = Arrays.asList("1", "2", "3", "4");  
        // 转换成Iterator实例
        Iterator<String> it = list.iterator(); 
        //遍历
        while (it.hasNext()) {
            System.out.println(it.next());
        }
  
    }
 }

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

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
 
public class Test2 {
 
   public static void main(String[] args) { 
       // Arrays类为我们提供了一种list的便捷创建方式
       List<String> list = Arrays.asList("1", "2", "3", "4"); 
       for (String s : list) {
          System.out.println(s);
       } 
   }
}

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)如果包含该键,则返回true
containsValue(Object value)如果包含该值,则返回true
get(Object key)根据键,返回相应的值对象
keySet()将该集合中的所有键以Set集合形式返回
values()将该集合中所有的值以Collection形式返回
remove(Object key)如果存在指定的键,则移除该键值对,返回键所对应的值,如果不存在则返回null
clear()移除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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值