十四、集合类框架的基本接口Collection、List、set、Map

1、Java 集合类里面最基本的接口有:

Java 集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。

Collection:代表一组对象,每一个对象都是它的子元素。
Set:不包含重复元素的 Collection。(无序不可重复)
List:有顺序的(collection)集合,也称为序列,并且可以包含重复元素。(有序可重复)

    实现List接口的用户,可以对插入列表中每个元素的插入位置进行精确地控制,用户可以根据元素的整数索引访问元素,并搜索列表中的元素。  
Map:可以把键(key)映射到值(value)的对象,键不能重复。

单向链表中的每一个元素我们都称之为节点(Entry),每个节点都有两部分来组成:集合存储的应用类型和指向下一个节点的内存地址,最后一个节点的指向为null.

双向链表是一个环状,每个节点由三部分组成:上一个整个节点的内存地址、object即数据、引用(中保存的内存地址指向下一个节点)

|List集合示例1|

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
  public class CollectionTest01 {
   public static void main(String[] args) { 
    //创建集合对象-->多态
    Collection c=new ArrayList();
    //添加元素 集合只能单个存储元素,并且只能存储引用类型
    c.add(1);
    c.add(new Integer(120));
  
    Student stu1=new Student("张三",20); 
    Student stu2=new Student("张三",20);
    c.add(stu1);
  
    //集合中元素个数
    System.out.println(c.size());
    //集合是否为空
    System.out.println(c.isEmpty());
    //集合中是否包含120这个元素
    System.out.println(c.contains(120));//true
    System.out.println(c.contains(stu2));//false
    /*m1和m2都是新建的对象,其内存地址是不一样的,但是下面的Manager类并没有重写equals方法,
     * 所以将来底层并一定会调用equals方法,调用的一定是Object的equals方法,而Object中的equals方法比较的是内存地址,
     * 所以m1是m1,m2是m2所以结果为false。但是已经不符合现实的业务逻辑了,可以通过重写Student类中的equals方法
     */
    c.clear();
    Iterator it=c.iterator();
    while(it.hasNext()){
       System.out.println(it.next());
    }
 }
}
class Student{
   String name;
   int ino;
   public  Student(String name,int ino){
      this.name=name;
      this.ino=ino;
   }
   @Override
   public boolean equals(Object obj) {
      if (this == obj)
       return true;
      if (obj == null)
       return false;
      if (!(obj instanceof Student))
       return false;
      Student other = (Student) obj;
      if (ino != other.ino)
       return false;
      if (name == null) {
       if (other.name != null)
        return false;
      } else if (!name.equals(other.name))
       return false;
      return true;
   }
}

|List示例2|

 

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class ArrayTest02 {
   public static void main(String[] args) {
    List list=new ArrayList();
  /*  

   Room r1=new Room(10,"张三");
    Room r2=new Room(16,"王五");

 

    list.add(r1);
    list.add(r2);//如果list集合中添加这两个元素后会报错:排序来源不明,强制类型转换异常
  */  
   list.add(1);
     list.add(12);
    list.add(0);
  
    Collections.sort(list);//该sort()法只能用来对Lise集合进行排序
    Iterator iterator=list.iterator();
    while(iterator.hasNext()){
     System.out.println(iterator.next());
    }
   }
}
class Room{
   int no;
   String name;
   public Room(int no,String name){
      this.no=no;
      this.name=name;
   }
}

 

 

|HashMap 和 Hashtable区别:|

转自:http://www.cnblogs.com/hcl22/p/6095927.html
HashMap和Hashtable都实现了Map接口,因为有很多特征相似,但是也有以下不同的地方:
1)HashMap 允许键和值是 null,而 Hashtable 不允许键或者值是 null;
2)Hashtable 是同步的,而 HashMap 不是。因此,HashMap 更适合于单线程环境,而 Hashtable适合于多线程环境;
3)HashMap 提供了可供应用迭代的键的集合,因此,HashMap 是快速失败的。另一方面,Hashtable 提供了对键的列举(Enumeration);
一般认为 Hashtable 是一个遗留的类

|HashSet|

1)HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。
2)哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每个元素是一个单项链表。每一个单项链表都有一个独一无二的hash值代表数组的下标。
在某个但向链表中的每一个节点上hash值是相等的,hash值实际上是key调用hashCode方法,在通过“hash function”转换成的值。
3)如何向哈希表中添加元素
  先调用被被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中不存在这个hash值,则直接加入元素。
如果该hash值已经存在继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加,如果equals方法返回ture
则放弃添加该元素。
4)HashSet其实是HashMap中的key部分,HashSet有什么特点,HashMap中的key, 应该具有相同的特点。
5)HashMap和HashSet初始化容量都是16,默认加载因子是0.75
加载因子表示的是当其容量达到初始容量的0.75时就开始自动扩容。
ArrayList和vector的默认初始化容量都是10,但是ArrayList扩大之后的容量是原容量的1.5倍,vector扩大之后的容量是原容量的2倍

|HashMap的实现原理详解:|

引用:http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532999.html

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class HashSetTest {

   public static void main(String[] args) {
    Employee e1=new Employee("100", "王英");
    Employee e2=new Employee("1002", "王英");
    Employee e3=new Employee("1003", "王英");
    Employee e4=new Employee("1004", "王英");
    Employee e5=new Employee("1004", "王英");
  
   Set eSet=new HashSet();
    eSet.add(e1);
    eSet.add(e2);
    eSet.add(e3);
    eSet.add(e4);
    eSet.add(e5);
    eSet.add(e5);//set 无序不可重复的集合,所以就算添加了两个e5元素,但是共计还是5个元素
 
    /*List eSet=new ArrayList();
    eSet.add(e1);
    eSet.add(e2);
    eSet.add(e3);
    eSet.add(e4);
    eSet.add(e5);
    eSet.add(e5);//list 集合有序可重复,所以添加了两个e5元素后,共计6个元素
    */
    System.out.println("集合中元素的个数:"+eSet.size());
  
    Iterator iterator=eSet.iterator();
    while(iterator.hasNext()){
     System.out.println(iterator.next());
    }
   }
}
class Employee{
   String no;
   String name;
   public Employee(String no,String name){
    this.no=no;
    this.name=name;
 }
   public boolean equals(Object ob){
    if(this==ob){
     return true;
  }
  if(ob instanceof Employee){
     Employee ep1=(Employee)ob;
     if(ep1.no.equals(this.no)&&ep1.name.equals(this.name)){
      return true;
     }
  }
    return false;
 }
 public int hashcode(String no){
   return no.hashCode();
   }
}

|SortedSet示例|

SortedSet 中的key特点是:无序不可以重复,但是存进去的元素可以按照大小自动排序;
如果想自动排序:key部分的元素需要:方法一:实现Comparable接口,方法二:单独编写一个比较器

因为Integer、String、Date这三种类型的都实现了Comparable接口,所以往SortedSet集合中添加元素后会自动排序

自动排序的方法一:实现Comparable接口

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortSetTest {
   public static void main(String[] args) throws ParseException {
    SortedSet sorts1=new TreeSet();
    sorts1.add(10);
    sorts1.add(3);
    sorts1.add(7);
    sorts1.add(200);
    sorts1.add(1);
  
    Iterator iterator=sorts1.iterator();
    while(iterator.hasNext()){
       System.out.println(iterator.next());
    }

    SortedSet sorts2=new TreeSet();
  
    String date1="2016-10-10";
    String date2="2012-01-10";
    String date3="2017-10-10";
    String date4="2013-10-12";
  
    SimpleDateFormat sdFormat=new SimpleDateFormat("yyyy-MM-dd");
    Date da1=sdFormat.parse(date1);
    Date da2=sdFormat.parse(date2);
    Date da3=sdFormat.parse(date3);
    Date da4=sdFormat.parse(date4);
  
    sorts2.add(da1);
    sorts2.add(da2);
    sorts2.add(da3);
    sorts2.add(da4);
  
    Iterator iterator2=sorts2.iterator();
    while(iterator2.hasNext()){
     Object element =iterator2.next();
     if(element instanceof Date){
         System.out.println(sdFormat.format(element));
    
     }
    }
   }
}

自己定义的类如果想在添加到SortedSet类中时实现自动排序,那么需要实现Comparable接口并重写compareTo方法

import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class UserSortedSetTest {

   public static void main(String[] args) {
    SortedSet sortedSet=new TreeSet();
    User user1=new User(10);
    User user2=new User(7);
    User user3=new User(60);
    User user4=new User(20);
    User user5=new User(90);
  
    sortedSet.add(user1);
    sortedSet.add(user2);
    sortedSet.add(user3);
    sortedSet.add(user4);
    sortedSet.add(user5);
  
    Iterator iterator=sortedSet.iterator();
    while(iterator.hasNext()){
     System.out.println(iterator.next());
    }
   }
}
class User implements Comparable{
   int age;
   String nameString;
 
   User(int age){
      this.age=age;
   }

   public String toString(){
      return "user[age="+age+"]";
   }
 
   @Override
   public int compareTo(Object ob) {
    int age1=this.age;
    int age2=((User)ob).age;
    return age1-age2;
   }
}

结果显示为:

user[age=7]
user[age=10]
user[age=20]
user[age=60]
user[age=90]

自动排序的方法二:单独编写一个比较器

Comparable 和 Comparator  接口各自的用处和区别:
1)Java 提供了只包含一个 compareTo()方法的 Comparable 接口。 这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。
2)Java 提供了包含 compare()和 equals()两个方法的 Comparator 接口。compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和 comparator 相等。只有当输入参数也是一个 comparator 并且输入参数和当前 comparator 的排序结果是相同的时候,这个方法才返回 true

备注:Map和Collection没有关系,Map是一对一存储,Collection是一个一个存储的;

一个类实现Comparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序Comparator可以看成一种算法的实现,将算法和数据分离;Comparable也可以在下面两种环境中使用:
(1)类没有考虑到比较问题而没有实现Comparable,可以通过Comparator 来实现排序,而不必改变对象本身;
(2)可以使用多种排序标准,比如升序、降序等

|Properties|

HashMap默认初始化容量是16,默认加载因子是0.75;
HashTable默认初始化容量是11,默认加载因子是0.75;
java.util.Properties;也是由key和values组成,但是key和value都是字符串类型

import java.sql.Driver;
import java.util.Properties;
public class PropertiesTest {
   public static void main(String[] args) {
    Properties p=new Properties();
    p.setProperty("driver", "Oracle.jdbc.driver.OracleDriver");
    //存的过程中如果key重复,则value覆盖。
    p.setProperty("username", "zhang");
    p.setProperty("username", "wang");

    String s1=(String) p.getProperty("driver");
    String s2=(String) p.getProperty("username");
  
    System.out.println(s1);
    System.out.println(s2);
   }
}

 

posted @ 2016-12-22 11:00  爱笑的berg  阅读(352)  评论(0)    收藏  举报