十四、集合类框架的基本接口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);
}
}

浙公网安备 33010602011771号