java集合类概要

来源:互联网 发布:linux 创建u盘启动盘 编辑:程序博客网 时间:2024/05/16 09:21

  集合类存放于java.util包中。主要为CollectionMap接口,集合类里存放的对象都是指对对象的引用,并非对象本身。


Collection

  java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。(jdk1.6开始,为了防范因为类型不统一造成的ClassCastException异常,对集合框架进行升级加入泛型)。
  这里写图片描述
  Collection接口是单值存放的最大接口,可以向其中保存多个单值数据,但是在一般的开发中,往往很少直接使用Collection接口进行开发,基本上都是使用其子接口。Collection接口中的方法如下图所示:这里写图片描述

Set接口

  set接口是Collection的一个子接口,set集合存储的元素是无序的,不可重复的。
  无序性:不是随机性,是指在底层的存储位置是无序的。
  不可重复性:不允许集合中存在重复项,后添加的相同元素不能够添加进去。
  Set接口最常见的实现类:HashSet,LinkedHashSet,TreeSet。
  

HashSet类

  特点:不能保证元素的排列顺序;不是同步的,不是线程安全;集合值可以是null(最有允许一个哦)。
  HashSet中使用哈希算法存储元素,因此具有很好的存取和查找性能:
  当向Set中添加元素时,首先调用此对象所在类的hashcode()方法,计算此对象的hash值来决定此对象的存储位置。若此位置之前没有存储对象,则直接存储。若此位置已有对象,则比较equals()方法比较这两个对象是否相同,如果相同,则后一个不能存储进去。要求添加进Set中元素所在的类,一定要重写hashcode()方法和equals()方法
  HashSet集合判断两个元素的相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。
  

import java.util.HashSet;import java.util.Set; class Person{   private String name;   private int age;   public Person(String name,int age){   this.name=name;   this.age=age; }   public boolean equals(Object obj){//覆写equals()方法     if(this==obj){     return true;     }     if(!(obj instanceof Person)){     return false;     }     Person p=(Person)obj; if(this.name.equals(p.name)&&this.age==p.age){     return true; }else{ return false;      }   }   public int hashCode(){//覆写hashCode()方法     return this.name.hashCode()*this.age();   }   public toString(){     return "姓名"+this.name+"年龄"+age;   }}public class Demo1{   public static void main(String[] args){   Set<Person> mySet=new HashSet<Person>();   mySet.add(new Person("王五"30);   mySet.add(new Person("王五"30);   mySet.add(new Person("li",30);   System.out.println(mySet);   }}

可以看出重复的项(王五 30)只出现一次。


LinkedHashSet类

  LinkedHashSet是HashSet的子类,也不是线程安全的。
  使用链表维护了一个添加进集合中的顺序(当我们遍历集合时,是按照添加进去的顺序实现的),改动较小,频繁遍历。
  对于普通的插入删除操作,比HashSet慢,遍历会更快。

TreeSet类

  TreeSet是SortedSet接口的实现类,是一种排序二叉树,TreeSet可以确保集合元素处于排序状态。
  TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
  TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0。向TreeSet中添加的应该是同一个类的对象,且最好是不可变对象。
  1.自然排序
  自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
  Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
  obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是 负数,则表明obj1小于obj2。
  
  2.定制排序
  自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法,该方法用于比较o1和o2的大小:如果该方法返回正整数,则表示o1大于o2;如果方法返回0,则表示o1等于o2,如果该方法返回负整数,则表示o1小于o2。

List接口

  list接口对Collection进行了简单的扩充。

返回值 方法 概要 E get(int index) 返回类表中指定位置的元素。 E set(int index, E element) 用指定元素替换列表中指定位置的元素。 void add(int index, E element) 在列表中的指定位置插入元素 E remove(int index) 移除列表中指定位置的元素 int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 int lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。 ListIterator listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 ListIterator listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。 List subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

List接口中元素的特点为:
  List中存储的元素实现类排序,而且可以重复的存储相关元素。两个常见的实现类为:ArrayList和LinkedList。

ArrayList

  1)ArrayList:
  ArrayList数组线性表的特点为:类似数组的形式进行存储,因此它的随机访问速度极快。
  ArrayList数组线性表的缺点为:不适合于在线性表中间需要频繁进行插入和删除操作。因为每次插入和删除都需要移动数组中的元素。

  • 如果在初始化ArrayList的时候没有指定初始化长度的话,默认的长度为10.
  • ArrayList在增加新元素的时候如果超过了原始的容量的话,ArrayList扩容ensureCapacity的方案为“原始容量*3/2+1”。
  • ArrayList是线程不安全的,切记Vector是ArrayList的多线程的一个替代品。

LinkedList

  适合于在链表中间需要频繁进行插入和删除操作,但是随机访问速度较慢,因为底层内部是双向循环链表(使用内部类Entry存储节点的信息)的结构。

Vector

  Vector基本上与ArrayList差不多,但是Vector是线程安全的。
  当数组长度不够时,扩容方案为一倍。
  Vector总是比ArrayList慢,应当尽量避免使用,效率很低。


Map接口

这里写图片描述
Map接口不是Collection接口的继承。主要存储“键值对”对象,根据键得到值,因此不允许键重复,但是允许值得重复。

HashMap

  是最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
  LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。

TreeMap

  TreeMap不允许key的值为null。是非同步的。能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。

Hashtable

  Hashtable 与HashMap类似,不同的是:它不允许记录的键或者值为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
  
几种遍历方法及对比

public static void main(String[] args) {  Map<String, String> map = new HashMap<String, String>();  map.put("1", "value1");  map.put("2", "value2");  map.put("3", "value3");  //第一种:增强for循环,遍历keySet  for (String key : map.keySet()) {   System.out.println("key= "+ key + " and value= " + map.get(key));  }  //第二种 迭代器,entrySet迭代(性能较好)  Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();  while (it.hasNext()) {   Map.Entry<String, String> entry = it.next();   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  }  //第三种:增强for循环,entrySet迭代(性能一般)  for (Map.Entry<String, String> entry : map.entrySet()) {   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  }  //第四种 迭代器,keySet迭代(性能较好)   Iterator<Integer> iterator = map.keySet().iterator();        Integer key;        while (iterator.hasNext()) {            key = iterator.next();            map.get(key);        }   /*只取value*/       System.out.println("通过Map.values()遍历所有的value,但不能遍历key");  for (String v : map.values()) {   System.out.println("value= " + v);  } }
0 0