黑马程序员——java编程那些事儿____集合框架

                                                                        -------android培训java培训、期待与您交流! ----------

 

一 集合类概述


(1)为什么出现集合类?

面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。

集合就是存储对象最常用的一种方式.

(2)数组和集合都是容器,两者有何不同?

数组长度固定,而集合长度是可变的

数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象

数组存储数据类型是固定的,而集合存储的数据类型不固定

(3)集合类的特点:

集合只能存储对象

集合的长度是可变的

集合可以存储不同类型的对象


二 集合类框架


   ()集合框架的构成及分


 



(二)集合类容器


  ⅠCollection 顶层接口

 

       (1)List:列表,元素是有序的(元素带角标索引),可以有重复元素,可以有null 元素     

   ①ArrayList(JDK1.2):底层的数据结构是数组数据结构,特点是查询速度快( 为带角标),但是增删速度稍慢,因为当元素多时,增删一个元素则所有元素的角标都得改变,线程不同步。默认长度是10,当超过长度时,按50%延长集合长度。    

   ②LinkedList(JDK1.2):底层数据结构式链表数据结构(即后面一个元素记录前一个),特点:查询速度慢,因为每个元素只知道前面一个元素,但增删速度快,因为元素再多,增删一个,只要让其前后的元素重新相连即可,线程是不同步的。

   ③Vector(JDK1.0):底层数据结构是数组数据结构.特点是查询和增删速度都很慢。默认长度是10,当超过长度时,100%延长集合长度。线程同步。(Vector功能跟ArrayList功能一模一样,已被ArrayList替代)

 

   List集合使用注意事项:

 

①ArrayList:

1)当往ArrayList里面存入元素没什么要求时,即只要求有序就行时;    

2)当往ArrayList里面存入元素要求不重复时,比如存入学生对象,当同名同姓时视为同一个人,则不往里面存储。则定义学生对象时,需复写equals方法,保证元素的唯一性。

public boolean equals(Object obj)
			   {
				  if(!(obj instanceof Student))
					 return false;
				  Student stu = (Student)obj;
				  return this.name.equals(stu.name)&&this.age==stu.age;
			    }

      则往ArrayList集合通过add存入学生对象时,集合底层自己会调用学生类的equals方法,判断重复学生则不存入。

      注:对于List集合,无论是addcontains、还是remove方法,判断元素是否相同,都是通过复写equals方法来判断!

import java.util.*;
/*
将自定义对象做为元素存到ArrayList集合中,并去除重复元素
*/
class ArrayListTest2 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();
		al.add(new Person("lisi01",30));//al.add(Object obj);//Object obj = new Person("lisi01",30);
		al.add(new Person("lisi02",31));
		al.add(new Person("lisi03",32));
		al.add(new Person("lisi02",31));
		al.add(new Person("lisi03",32));
		al.add(new Person("lisi04",33));

		//删除重复的元素
		al = singleElement(al);

		//删除
		sop("remove 03 : "+al.remove(new Person("Lisi03",33)));

		//迭代
		Iterator it = al.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();//需要类型一致,要做强转
			sop(p.getName()+"::"+p.getAge());
		}
	}
	public static ArrayList singleElement(ArrayList al)
	{
		//定义一个临时容器
		ArrayList newAl = new ArrayList();
		Iterator it = al.iterator();
		while (it.hasNext())
		{
			Object obj = it.next();
			if (!newAl.contains(obj))
				newAl.add(obj);
		}
		return newAl;
	}
}
class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//重写equals,List集合判断元素是否相同,依据的是元素的equals方法
	public boolean equals(Object obj)
	{
		
		if (!(obj instanceof Person))
			return false;
		Person p = (Person)obj;
		System.out.println(this.name+"..."+p.name);
		return this.name.equals(p.name)&&this.age==p.age;
	}

	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}


 

②LinkedList

1)LinkLedist的特有方法:

 boolean offerFirst(E e)  在此列表的开头插入指定的元素。

 boolean offerLast(E e) 在此列表末尾插入指定的元素。

 E peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null

 E peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null

 E pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null

 E pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null

2)通过LinkLedist的特有方法,可以实现某些数据特殊方式的存取,比如堆栈和队列。

   ③一般情况下,使用哪种List接口下的实现类呢?

     如果要求增删快,考虑使用LinkedList

     如果要求查询快,考虑使用ArrayList

     如果要求线程安全,考虑使用Vector

 

      (2)Set:集合,元素是无序的(因为没有索引),元素不可以重复。可以有null元素。

①HashSet(JDK1.2):底层数据结构是哈希表、存取速度快、元素唯一、线程不同步。保证性元素唯一的原理:

    先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true(HashSet里面存的自   定义元素要复写hashCodeequals方法,以保证元素的唯一性!)

②TreeSet:底层数据结构式二叉树。可以对Set集合中的元素进行排序。元素有序、线程不同步。  保证元素唯一性的依据:compareTo方法return 0

          TreeSet排序的第一种方式:

                让元素自身具备比较性,实现Compareble接口,覆盖compareTo方法,此方式是元素的自然顺序  

          TreeSet排序的第二种方式: 

                当元素自身不具备比较性(比如存储学生对象时)或者具备的比较性不是我们所需要的比较性时(比如想字符串的长度排序),此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时,就让集合具备比较方式。即定义一个类,实现Comparator接口,覆盖compare方法。

 

Set集合使用注意事项:

 

①HashSet:

 通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象,比如学生对象时,虽然是new的两个学生对象,但是当他们nameage一样时,我们认为是同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时,在定义对象的类中通常复写hashCodeequals方法。

public int hashCode()
			      {
					return name.hashCode()+age*39;
			      }
			      public boolean equals(Object obj)
			      {
					if(!(obj instanceof Student))
						return false;
					Student stu = (Student)obj;
					return this.name.equals(stu.name)&&this.age==stu.age;
			      }


 

 HashSet是如何保证元素唯一性的呢?

  **如果两元素的hashCode值不同,则不会调用equals方法

  **如果两元素的hashCode值相同,则继续判断equals是否返回true

  **hashCodeequals方法虽然定义在自定义对象类里面,但不是我们手动调用

                       而是往HashSet集合里面存储元素的时候,集合底层自己调用hashCode

                       和equals它自己拿对象去判断,自己判断两元素是否是同一个元素。

import java.util.*;
/*
往HashSet集合中存入自定义元素,性名和年龄相同为同一个人,为重复元素
*/
class  HashSetTest
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{

		HashSet hs = new HashSet();
		hs.add(new Person("a1",11));//al.add(Object obj);//Object obj = new Person("a1",11);
		hs.add(new Person("a2",12));
		hs.add(new Person("a3",13));
		hs.add(new Person("a4",14));
		hs.add(new Person("a3",13));
		hs.add(new Person("a4",14));
		
		//判断
		sop("al:"+hs.contains(new Person("a2",12)));

		//删除
		hs.remove(new Person("a4",13));

		//迭代
		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();//需要类型一致,要做强转
			sop(p.getName()+"::"+p.getAge());
		}
	}
}

class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
     //覆盖hashCode方法
	public int hashCode()
	{
		System.out.println(this.name+".....hashCode");
		return name.hashCode()+age*34;
	}

	//重写equals方法
	public boolean equals(Object obj)
	{
		
		if (!(obj instanceof Person))
			return false;
		Person p = (Person)obj;
		System.out.println(this.name+"..equals.."+p.name);
		return this.name.equals(p.name)&&this.age==p.age;
	}
	
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}


②TreeSet:

TreeSet要求往里面存的元素具备比较性,否则会报错。

TreeSet排序的第一种方式:

        让元素自身具备比较性,定义对象类,实现Compareble接口,复写compareTo方法,此方式是元素的自然顺序

  class Student implements Comparable
				  {
					private String name;
					private int age;
					public Student(String name,int age)
					{
						this.name=name;
						this.age=age;
					}
					public String getName()
					{
						return name;
					}
					public int getAge()
					{
						return age;
					}
					public int compareTo(Object obj)
					{
						if(!(obj instanceof Student))
							throw new RuntimeException("不是学生对象!");
						Student stu = (Student)obj;
						int num = this.age-stu.age;
						if(num==0)
							return this.name.compareTo(stu.name);
						return num;
					}
				  }


 

TreeSet排序的第二种方式:

        让集合具备比较性当元素自身不具备比较性(比如存储学生对象时)或者具备的比较性不是我们所需要的比较性时(比如想字符串的长度排序),此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时,就让集合具备比较方式。即定义一个类,实现Comparator接口,覆盖compare方法。

class StringLengthComparator implements Comparator
				 {
					public int compare(Object obj1,Object obj2)
					{
						String s1 = (String)obj1;
						String s2 = (String)obj2;
						int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
						if(num==0)
							return s1.compareTo(s2);
						return num;
					}
				 }
				 class TreeSetTest
				 {
					public static void main(String[] args)
					{
						TreeSet ts = new TreeSet(new StringLengthComparator());
						ts.add("addfg");
						ts.add("dfg");
						ts.add("agtuug");
						ts.add("vgjkg");
						sop(ts);
					}
				 }

				 
								 	
		注意:基本数据类型或字符串对象均实现了Comparable接口,故同种类型基本数据间具备比较性,即自然顺序。


 

 

Ⅱ Map 顶层接口

该集合存储的是键值对,而且键是唯一的,MapSet很像,Set集合底层就是使用了Map集合。

Map集合没有迭代器,要取出元素必须先将Map集合转换成Set集合才能遍历元素

    ⑴HashTable(JDK1.0):底层是哈希表数据结构;不可以使用null键和null值;用作键的对象必须实现hashCodeequals方法来保证键的唯一性,线程同步,效率低

     (2)HashMap(JDK1.2):底层是哈希表数据结构;允许使用null键和null值;线程不同步,效率高;保证元素唯一性的原理:先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true(HashSet里面存的自定义元素要复写hashCodeequals方法,以保证元素的唯一性!)

class Student {
			private String name;
			private int age;
			public Student(String name, int age) {
				super();
				this.name = name;
				this.age = age;
			}
			public int getAge() {
				return age;
			}
			public void setAge(int age) {
				this.age = age;
			}
			public String getName() {
				return name;
			}
			public void setName(String name) {
				this.name = name;
			}
			
			@Override
			public int hashCode(){
				return name.hashCode()+age*34;
			}
			@Override
			public boolean equals(Object obj){
				
				if(!(obj instanceof Student))
					return false;
				Student stu = (Student)obj;
				return this.name.equals(stu.name)&&this.age==stu.age;
			}
		public class HashMapDemo1 {
			public static void main(String[] args) {
				Map<Student , String> hmap = new HashMap<Student , String>();
				hmap.put(new Student("001",20), "beijing");
				hmap.put(new Student("002",25), "hebei");
				hmap.put(new Student("003",50), "hainan");
				hmap.put(new Student("001",20), "beijing");
				
				System.out.println(hmap.size());
				Set<Student> keySet = hmap.keySet();
				Iterator<Student> it = keySet.iterator();
				while(it.hasNext()){
					Student stu = it.next();
					String addr = hmap.get(stu);
					System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
				}	
			}	
		}			


(3)TreeMap(JDK1.0):底层是二叉树结构;允许使用null键和null值;线程不同步;可以给Map集合中的键进行排序.

  TreeMap排序的第一种方式:

               让元素自身具备比较性,实现Compareble接口,覆盖compareTo方法,此方式是元素的自然顺序 

 

          TreeMap排序的第二种方式:

               让集合具备比较性当元素自身不具备比较性(比如存储学生对象时)或者具备的比较性不是我们所需要的比较性时(比如想字符串的长度排序),此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时,就让集合具备比较方式。即定义一个类,实现Comparator接口,覆盖compare方法。

 

class Student implements Comparable<Student>{
			private String name;
			private int age;
			public Student(String name, int age) {
				super();
				this.name = name;
				this.age = age;
			}
			public int getAge() {
				return age;
			}
			public void setAge(int age) {
				this.age = age;
			}
			public String getName() {
				return name;
			}
			public void setName(String name) {
				this.name = name;
			}
			@Override
			public int compareTo(Student stu) {
				int num = new Integer(this.age).compareTo(new Integer(stu.age));
				if(num==0)
					return this.name.compareTo(stu.name);
				return num;
			}			
		}

		public class HashMapDemo1 {
			public static void main(String[] args) {
							
				Map<Student , String> tmap = new TreeMap<Student , String>();
				tmap.put(new Student("001",20), "beijing");
				tmap.put(new Student("002",25), "hebei");
				tmap.put(new Student("003",50), "hainan");
				tmap.put(new Student("001",20), "beijing");
				
				System.out.println(tmap.size());

  //hashMap的第一种取出方式 keySet
				Set<Student> keySet1 = tmap.keySet();
				Iterator<Student> it1 = keySet1.iterator();
				while(it1.hasNext()){
					Student stu = it1.next();
					String addr = tmap.get(stu);
					System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);		
				}
  /*
  //hashMap的第二种取出方式 entrySet
  	Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
  	Iterator<Map.Entry<Student,String>> ite = entrySet.iterator();
  	while(ite.hasNext())
  	{
  		Map.Entry<Student,String> me = ite.next();
  		Student stu = me.getKey();
  		String addr = me.getValue();
  		System.out.println(stu+"\\\\"+addr);
  	}
  */
			}
		}


(三)集合类各容器方法

     1接口Collection方法摘要(没有构造方法)

a)添加:

boolean add(E e)

boolean addAll(Collection c)

b)删除:

void clear():清空容器

boolean remove(Objec object):

boolean removeAll(Collection c):

c)判断:

boolean contains(Object object):判断是否包含此元素

boolean containsAll(Collection c):判断是否包含一堆元素

boolean equals(Object object):比较此collection与指定对象是否相等

boolean isEmpty():判断是否集合为空

d)获取:

Iterator iterator():取出

          Iterator it = al.iterator();

           While(it.hasNext())

           {

                  System.out.println(“next:”+it.next());

           }

int hashCode():返回此collection的哈希值

int size():返回此collection中元素的个数

boolean retainAll(Collection c):取交集

Object toArray():返回此collection中所有元素的数组

T[] toArray(T[] a):返回包含此collection中所有元素的数值。

 

       2 List集合子类及其方法

(1)List接口是Collection接口的一个子接口。

(2)List接口中的元素有如下特点(对角标的操作都是特有方法,因为有序)

A:元素有序(存储顺序和取出顺序一致)

B:元素可以重复

(3)List接口中的特有方法

add(int index,Object obj):在指定位置加入元素

remove(int index):移除指定位置的元素

set(int index,Object obj):修改指定位置的元素

get(int index):获取指定位置的元素

indexOf(Object obj):获取指定元素的位置

subList(int start,int end):从一个大的List中截取一个小的List

listIterator():返回一个List接口特有的迭代器

ListIterator it = al.ListIterator();

while(it.hasNext())

{

        Object obj = it.next();

         if(ibj.equals(“java02”))

                 it.add(“java03”);

}

while(it.hasPrevious())

{

           System.out.println(“pre:”+it.previous());

}

(4)List接口中子类及其方法

 

    1)ArrayList

       |--->构造方法摘要:(少用,不是重点)

ArrayList():构造一个初始容量为 10 的空列表。

ArrayList(Collection<? extends E> c): 构造一个包含指定 collection 的元素的列表,    

ArrayList(int initialCapacity): 构造一个具有指定初始容量的空列表

 |--->方法摘要:

a)添加:

boolean add(E e): 将指定的元素添加到此列表的尾部。

void add(int index, E element): 将指定的元素插入此列表中的指定位置。

boolean addAll(Collection<? extends E> c):按照指定 collection 的迭代器所返回的元素顺序,

 将该 collection 中的所有元素添加到此列表的尾部 

boolean addAll(int index, Collection<? extends E> c): 从指定的位置开始,将指定 collection

       中的所有元素插入到此列表中。 

b)删除:

void clear(): 移除此列表中的所有元素。

E remove(int index): 移除此列表中指定位置上的元素。 

boolean remove(Object o): 移除此列表中首次出现的指定元素(如果存在)。

protected  void removeRange(int fromIndex, int toIndex): 移除列表中索引在 fromIndex(包括)

                                和  toIndex(不包括)之间的所有元素。

boolean removeAll(Collection<?> c): 从列表中移除指定 collection 中包含的其所有元素

 

c)获取:

E get(int index): 返回此列表中指定位置上的元素。

For(int x=0;x<al.size();x++)

{

           System.out.println(“al(”+x+”)=”+al.get(x));

}

int indexOf(Object o): 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,

                        则返回 -1

int lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含

                         索引,则返回 -1。   

public List<E> subList(int fromIndex,int toIndex): 返回列表中指定的 fromIndex(包括 )    和 toIndex(不包括)之间的部分视图。

Iterator<E> iterator(): 返回按适当顺序在列表的元素上进行迭代的迭代器。

ListIterator<E> listIterator(int index):返回列表中元素的列表迭代器(按适当顺序)从列表的指定位置

                                   开始。

d)修改:(特有方法!!)

E set(int index, E element): 用指定的元素替代此列表中指定位置上的元素。

 

(2)LinkedList:

|--->构造方法摘要:

LinkedList(): 构造一个空列表。 

LinkedList(Collection<? extends E> c): 构造一个包含指定 collection 中的元素的列表,

       这些元素按其 collection 的迭代器返回的顺序排列。

|--->方法摘要:(特有的)

a)添加

void addFirst(E e): 将指定元素插入此列表的开头。 

void addLast(E e): 将指定元素添加到此列表的结尾。 

a)获取元素,但不删除元素

 E get(int index): 返回此列表中指定位置处的元素。           

 E getFirst(): 返回此列表的第一个元素。          

 E getLast(): 返回此列表的最后一个元素。

c)获取元素且删除元素

 E remove(): 获取并移除此列表的头(第一个元素)。          

 E remove(int index): 移除此列表中指定位置处的元素。         

 boolean remove(Object o): 从此列表中移除首次出现的指定元素(如果存在)。         

 E removeFirst(): 移除并返回此列表的第一个元素。 

 E removeLast(): 移除并返回此列表的最后一个元素。

d)修改

 E set(int index, E element) 将此列表中指定位置的元素替换为指定的元素。

 

(3)Vector

|--->构造方法摘要:

Vector(): 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。          

Vector(Collection<? extends E> c):  构造一个包含指定 collection 中的元素的向量,

    这些元素按其 collection 的迭代器返回元素的顺序排列。

|--->方法摘要:

a)添加:

boolean add(E e): 将指定元素添加到此向量的末尾。

void add(int index, E element): 在此向量的指定位置插入指定的元素。         

boolean addAll(Collection<? extends E> c):

 将指定 Collection 中的所有元素添加到此向量的末尾, 

 按照指定 collection 的迭代器所返回的顺序添加这些元素。 

boolean addAll(int index, Collection<? extends E> c): 在指定位置将指定 Collection 中的

                                       所有元素插入到此向量中。

b)获取:

Enumeration<E> elements(): 返回此向量的组件的枚举。

   Vector特有的取出方式:

   枚举和迭代器很像,其实枚举和迭代器是一样的,只是因为枚举的名称和方法的名称

   名字都过长,所以枚举被迭代器取代了。

枚举Enumeration的方法摘要:

 boolean hasMoreElements(): 测试此枚举是否包含更多的元素。 

 E nextElement(): 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下

                                一 个元素。 

    3 Set集合子类及其方法

     (1)HashSet:它不保证set的迭代顺序;特别是它不保证该顺序恒久不变.此类允许使用null元素。 

   |--->构造方法:

    HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是16,加载因子是 0.75

    HashSet(Collection<? extends E> c) 构造一个包含指定 collection 中的元素的新 set

   |--->方法摘要:

boolean add(E e) 如果此 set 中尚未包含指定元素,则添加指定元素。   

void clear() 从此 set 中移除所有元素。   

Object clone() 返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。    

boolean contains(Object o) 如果此 set 包含指定元素,则返回 true。    

boolean isEmpty() 如果此 set 不包含任何元素,则返回 true。    

Iterator<E> iterator() 返回对此 set 中元素进行迭代的迭代器。    

boolean remove(Object o) 如果指定元素存在于此 set 中,则将其移除。    

int size() 返回此 set 中的元素的数量(set 的容量)。 

 

(2)TreeSet:使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序.

 |--->构造方法:

TreeSet() 构造一个新的空 set,该set根据其元素的自然顺序进行排序。          

TreeSet(Collection<? extends E> c) 构造一个包含指定 collection 元素的新 TreeSet

它按照其元素的自然顺序进行排序。 

TreeSet(Comparator<? super E> comparator)构造一个新的空TreeSet它根据指定比较器进行排序。

 |--->方法摘要:

 a)添加:

  boolean add(E e)  将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。

  boolean addAll(Collection<? extends E> c) 将指定 collection 中的所有元素添加到此 set 中。

  b)删除:

   void clear() 移除此 set 中的所有元素。 

   boolean remove(Object o)  将指定的元素从 set 中移除(如果该元素存在于此 set 中)。 

   E pollFirst() 获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。 

   E pollLast() 获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。 

c)获取:

   Iterator<E> iterator()  返回在此 set 中的元素上按升序进行迭代的迭代器。

   E first() 返回此 set 中当前第一个(最低)元素。

   E last() 返回此 set 中当前最后一个(最高)元素。

   int size()  返回 set 中的元素数(set 的容量)。

d)判断:

  boolean isEmpty()  如果此 set 不包含任何元素,则返回 true。 

  boolean contains(Object o) 如果此 set 包含指定的元素,则返回 true。 

 

   4 Map集合方法

|--->方法摘要:

   a)添加:

      V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。           

      void putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中

   b)删除:

          void clear()  从此映射中移除所有映射关系(可选操作)。 

          V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

   c)判断

          boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。 

          boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true

          boolean isEmpty() 如果此映射未包含键-值映射关系,则返回 true。 

        d)获取

          int size() 返回此映射中的键-值映射关系数。 

          Collection<V> values()  返回此映射中包含的值的 Collection 视图。

         Map集合没有迭代器,以下是Map的两种取出方式:

      第一种:Set<K> keySet()

返回此映射中包含的键的Set视图,将Map集合中所有的键存入Set集合,然后再通过Set集合的

迭代器取出所有的键,再根据get方法获取每个键的值;

 

      第二种:Set<Map.Entry<K,V>> entrySet() 

返回此映射中包含的映射关系的Set视图,将Map集合中的映射关系存入到Set集合中,

这个映射关系的数据类型是Map.entry,再通过Map.Entry类的方法再要取出关系里面的键和值

Map.Entry的方法摘要:

boolean equals(Object o)  比较指定对象与此项的相等性。   

K getKey()  返回与此项对应的键。   

V getValue() 返回与此项对应的值。    

int hashCode() 返回此映射项的哈希码值。

V setValue(V value) 用指定的值替换与此项对应的值(特有!!!)

 

import java.util.*;
class MapDemo 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();


		//添加	
		map.put("01","zhangshan1");
		map.put("01","zhangshan4");//添加的时候,如果出现相同的建,那么后添加的值会覆盖原有建对应
  //的值,并put方法会返回被覆盖的值
		map.put("02","zhangshan2");
		map.put("03","zhangshan3");

		/*
		//打印
		System.out.println(map);

		//判断
		System.out.println("containsKey:"+map.containsKey("02"));

		//获取
		System.out.println("get:"+map.get("02"));

			注意://可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断
				map.put("04",null);
				System.out.println("get:"+map.get("04"));

		//获取map集合中的所有值
		Collection<String> coll = map.values();
		System.out.println(coll);

		//删除
		System.out.println("remove:"+map.remove("02"));

		*/

/*keySet*/

		//先获取map集合的所有键的Set集合,keySet();
		Set<String> keySet = map.keySet();
		//有了Set集合,就可以获取其迭代器
		Iterator<String> it = keySet.iterator();

		while (it.hasNext())
		{
			String s = it.next();
			//有了键就可以通过map集合的get方法获取其对应的值
			String value = map.get(s);
			System.out.println("key:"+s+",value:"+value);

		}

/*entrySet


		//将Map集合中的映射关系取出,存入到Set集合中
		Set<Map.Entry<String,String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String,String>> it = entrySet.iterator();

		while (it.hasNext())
		{
			Map.Entry<String,String> me = it.next();
			String key = me.getKey();
			String value = me.getValue();
			
			System.out.println("key:"+key+",value:"+value);
		}
*/

	}
}


 

(四)Map集合和Collection集合的区别

1 Map中一次存储是键值对。

        Collection中一次存储是单个元素。

2 Map的存储使用的put方法。

        Collection存储使用的是add方法。

 

3 Map集合没有迭代器,Map的取出,是将Map转成Set,在使用迭代器取出。

        Collection取出,使用就是迭代器。

4 如果对象很多,必须使用集合存储。

        如果元素存在着映射关系,可以优先考虑使用Map存储或者用数组,

       如果没有映射关系,可以使用Collection存储。

(五)迭代器与迭代列表

 1)迭代器:Iterator(Map集合没有迭代器)

(1)迭代器就是取出集合元素的方式

(2)迭代器的作用

因为每个集合中元素的取出方式都不一样,于是就把元素的取出方式进行抽取,并定义在集合内部,

这样取出方式就可以直接访问集合内部的元素;

而每个容器的数据结构不同,所以取出动作的细节也不一样,但是有共性内容:判断和取出。

那么就将共性内容进行抽取,从而形成了接口Iterater

(3)获取迭代器的方法:

Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。 

Iterator<E> iterator() 返回在此 set 中的元素上进行迭代的迭代器。      

(3)迭代器方法:

boolean hasNext() 如果仍有元素可以迭代,则返回 true

E next() 返回迭代的下一个元素。       

void remove() 从迭代器指向的collection中移除迭代器返回的最后一个元素(可选操作)。

Iterator<Person> it = al.iterator();

while(it.hasNext())

{

Person p = it.next();

sop(p.getName()+"::"+p.getAge());

}

 

2)列表迭代器:(List集合特有的迭代器)ListIterator

(1)List集合特有的迭代器ListIteratorIterator的子接口,在迭代时,不可以通过集合对象的

      方法操作集合中的元素,因为会发生ConcurrentModificationException(当方法检测到对象的并发修改,

       但不允许这种修改时,抛出此异常)

(2)Iterator方法有限,只能对元素进行判断、取出和删除的操作

       ListIterator可以对元素进行添加和修改动作等。

(3)获取列表迭代器方法:

ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 

ListIterator<E> listIterator(int index) 

返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。 

(4)列表迭代器方法:

void add(E e) 将指定的元素插入列表(可选操作)。

boolean hasPrevious()  如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。 

int nextIndex() 返回对 next 的后续调用所返回元素的索引。         

E previous() 返回列表中的前一个元素。    

int previousIndex() 返回对 previous 的后续调用所返回元素的索引。    

void set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。 

  public static void listIterator()
  {
  ArrayList al = ArrayList();
  al.add(“java01”);
  al.add(“java04”);
  
  ListIterator it = al.ListIterator();
  while(it.hasNext())//向前遍历
  {
  Object obj = it.next();
  if(ibj.equals(“java02”))
  it.add(“java03”);
  }
  while(it.hasPrevious())//向后遍历
  {
  System.out.println(“pre:”+it.previous());
  }
  
  }



三 集合类各种容器的使用注意细节:

(1)迭代器:

**迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException

  也就是在迭代循环中调用一次next方法一次就要hasNext判断一次,比如语句

  sop(it.next()+"..."+it.next())会发生上述异常。

**迭代器的next方法返回值类型是Object,所以要记得类型转换,应用泛型后就不用强转

(2)List集合:

**List集合里面的元素因为是带角标,所以List集合里面的元素都是有序的,

  另外List集合可以包含重复元素,也可以包含null。  

**List集合有迭代器Iterator,还有一个特有迭代器列表ListIterator

**List集合中判断元素是否相同都是用equals方法,无论containsremove都依赖equals方法

  如往ArrayList集合里面存放学生,同名同年龄视为同一个人,此时就需在学生类复写Object

  里面的equals方法(非常重要!!!要注意!!)

(3)Set集合:

**Set接口里面存放的是元素是无序的,不可以有重复元素,可以包含null

**Set集合只有一种取出方式,就是迭代器Iterator(list集合有getIterator

**Set集合功能和Collection是一致的,没有特殊方法

    |--->HashSet:

**集合里面存放的元素是无序的,唯一的

**底层数据结构是哈希表,哈希表结构的数据都是无序的,哈希表结构的操作效率都高效

**线程不同步

**保证元素唯一性的原理是:通过复写hashCodeequals方法

****如果两元素的hashCode值相同,则继续判断两元素equals是否为真

****如果两元素的hashCode值不同,则不会调用equals方法。

**当我们往HashSet集合存放自定义的元素时(比如学生对象),通常都要复写hashCodeequals方法,而且hashCodeequals方法不通过我们调用,HashSet集合底层内部自己调用,自己拿元素去比较

    |--->TreeSet

**TreeSet集合可以对存放的元素进行排序,弥补了Set集合元素无序的缺点,且元素是唯一的

**底层数据结构是二叉树,二叉树结构都是有序的

**线程不同步

**TreeSet集合要求往集合里存放的元素自身具备比较性,否则会报错

**TreeSet集合保证元素唯一性的依据是:通过compareTo或者compare方法中的来保证元素的唯一性。

TreeSet排序的第一种方式:让元素自身具备比较性,

定义元素类实现Compareble接口,覆盖compare方法,

此方式是元素的自然顺序。

TreeSet排序的第二种方式:让集合具备比较性

当元素自身不具备比较性或者具备的比较性不是

我们所需要的比较性时,此时就需要让集合具备自定义的比较性。

那如何让集合自身具备比较性呢?

可在集合初始化时,就让集合具备比较方式。

即定义一个类,实现Comparator接口,覆盖compare方法。

注:

**判断元素唯一时,当主要条件一样时,判断次要条件

**两种排序方式都在时,以比较器为主!!!

(4)Map集合:

|--Hashtable

底层是哈希表结构

线程安全的,并且键和值不能为null

|--HashMap

底层是哈希表结构

线程不安全的,键和值可以为null

|--LinkedHashMap

底层是链表和哈希表

线程不安全

|--TreeMap

底层是二叉树

线程不安全的

 




   -------android培训java培训、期待与您交流! ----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值