黑马程序员 笔记(十三)——集合框架

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

集合类

    面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式.在很多情况下,我们不知道在程序中需要创建多少个对象,这时就不能依靠定义引用对象的变量来持有每一个对象。存储对象的容器就能帮我们解决这样的问题,而集合便是这样的容器。

数组和集合类同是容器,有何不同
  • 数组:存储对象,但长度是固定的,存储基本数据类型。
  • 集合:存储对象,但长度是可变,存储对象。
集合的特点:
  • 集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
  • 集合中存贮的是对象的地址。
集合框架概述
  1. Java中集合类定义主要是在java.util.*包下面。
  2. 集合的框架体系:
为什么需要这么多容器?
  1. 因为每一个容器对数据的存贮方式都有不同,这种存贮方式称为:数据结构
    • Collection: 根接口(共性方法)(List:Set:)
      1. 增:add()方法的参数是Object,以便于接收任意类型的对象
        • boolean add(E e):向容器中添加对象
        • addAll(Collcetion<? extends E> c):将指定 collection 中的所有元素都添加到此 collection 中
        • void clear():移除此 collection 中的所有元素
        • boolean remove(Object o):从此 collection 中移除指定元素的单个实例,如果存在的话返回true
        • boolean removeAll(Collcetion<?> c)将集合中相同的部分去掉。
      2. 判断
        • boolean contains(Object o):判断是否包含某一个对象
        • boolean containsAll(Collcetion<?> c):如果此 collection 包含指定 collection 中的所有元素,则返回true
        • boolean equals(Object o):比较此 collection 与指定对象是否相等。
        • boolean isEmpty():判断容器中是否有对象。
        1. 迭代器:取出集合内部元素的一个接口,该接口的子类定义在集合的内部。这样就可以直接访问集合内部的元素。因为每一个容器的数据结构不同,所以取出动作的实现细节也不同,但是都有共性内容(判断和取出)。因此将其共性抽取。以后任何集合只要在内部实现Iterator接口,就可以将其元素取出。
        2. iterater iterater()
      3. 代码示例:
        • import java.util.*;
          class CollectionDemo 
          {
          	public static void main(String[] args) 
          	{
          		ArrayList a1 = new ArrayList();
          		ArrayList a2 = new ArrayList();
          
          		//添加元素(对象)	运用  add(Object obj)
          
          		a1.add("Where");
          		a1.add("there");
          		a1.add("is");
          
          		a2.add("I");
          		a2.add("Love");
          		a2.add("You");
          
          		a1.addAll(a2);
          
          		//获取个数,集合的长度
          		sop("a1的Size:"+a1.size()+"\n");
          
          		//删除元素
          		sop(a1.remove("You")+"\n");	//返回值为布尔型
          		sop(a1+"\n");
          
          		//取交集
          		sop(a2.retainAll(a1));//返回的结果是布尔型,表示是否有交集
          		sop("a1和a2的交集是:"+a2+"\n");//a1里现在是a1与a2的交集
          
          		//取出元素
          					//通过Iterator取出集合内的元素。
          		for (Iterator it=a1.iterator();it.hasNext() ; )
          		{
          			sop(it.next()+"\t");
          		}
          	}
          
          	public static void sop(Object o)
          	{
          		System.out.print(o);
          	}
          }

                    List:(Collection的子类之一)
                    1. 特点:元素是有序的,元素可以重复,因为该集合体系中有索引
                    2. 常见子类对象:
                      1. ArrrayList:底层的数据结构使用的是数组结构
                        • 特点:查询速度很快,因为有索引(角标),但增删速度稍慢。是线程不同步的。
                      2. LinkedList:底层使用的是链表的结构
                        • 特点:增删速度很快,但查询速度稍慢,因为每一个元素都链接到前一元素
                      3. Vector:底层是数组结构,线程同步,被ArrayList代替。
                    3. List中的特有方法:(凡事可以操作角标的方法都是该体系的特有方法)
                        1. void add(index,E e):在指定位置添加对象
                        2. void add(index,Collection);在指定位置插入一个集合
                        1. E remove(index):删除指定位置上的元素
                        1. set(index,element):修改指定位置上的元素
                        1. E get(index):获取指定位置的元素。
                        2. 通过迭代器Iterator进行取出:取出所有的元素。
                          • 迭代器是取出元素的方式。把取出方式定义在集合的内部,这样取出方式就可以直接访问集合的内的元素。
                          • 因为每一个容器的数据结构有所不同,所以取出的动作也不一样。但是都有共性的内容,判断和取出。因此就把这些共性的方法抽取出来,形成Iterator接口。
                        3. int indexOf(Object o):获取该对象在容器中的位置。
                        4. List subList(int fromIndex, int toIndex)获取指定到指定结束位置的对象。
                        5. 列表迭代器:ListIterator是Iterator的子接口
                          • 在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常,所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的。只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取
                    4. LinkedList:(链接列表)
                      1. 特有方法:
                        • void addFirst(E e)
                        • void addLast(E e)
                        • E get First()//get方法获取元素,但是不删除元素。当集合为空时,则抛出没有这个元素的异常。
                        • E getLast()
                        • E remove()//remove方法获取元素,并且删除该元素。当集合为空时,则抛出没有这个元素的异常
                        • E remove(int index)
                        • E removeFirst()
                        • E removeLast()
                        • 在JDK1.6中出现了替代方法
                          • offerFirst()   替代void add方法
                          • offerLast()
                          • peekFirst()替代get方法
                          • peekList()
                          • pollFirst()替代remove方法
                          • pollLast()
                      2. LinkedList示例:
                        • /*
                          使用LinkedList模拟一个堆栈或者队列数据结构。
                          
                          堆栈:先进后出  如同一个杯子。
                          队列:先进先出 First in First out  FIFO 如同一个水管。
                          */
                          
                          import java.util.*;
                          class DuiLie
                          {
                          	private LinkedList link;
                          
                          	DuiLie()
                          	{
                          		link = new LinkedList();
                          	}
                          	
                          	public void myAdd(Object obj)
                          	{
                          		link.addFirst(obj);
                          	}
                          	public Object myGet()
                          	{
                          		return link.removeFirst();
                          	}
                          	public boolean isNull()
                          	{
                          		return link.isEmpty();
                          	}
                          }
                          
                          
                          class  LinkedListTest
                          {
                          	public static void main(String[] args) 
                          	{
                          		DuiLie dl = new DuiLie();
                          		dl.myAdd("java01");
                          		dl.myAdd("java02");
                          		dl.myAdd("java03");
                          		dl.myAdd("java04");
                          
                          		while(!dl.isNull())
                          		{
                          			System.out.println(dl.myGet());
                          		}
                          	}
                          }
                          


                    5. Vector方法中的特殊方法(枚举)
                      1. Enumeration elements()就是vector特有的取值方式(枚举)。相当与迭代器。
                        • Enumeration elements()中的方法:
                          • boolean hasMoreElements()
                          • E nextElements()
                      2. 由于枚举的名称以及方法的名称都过长,所以被迭代器取代了.


                    Set
                    1. 特点:没有索引,元素不可重复,存入和取出的顺序不一定一致。
                    2. 功能:和ArrayList
                    3. 常见子类:
                      1. hashSet():底层数据结构是哈希表。
                      2. TreeSet():底层的数据结构是二叉树。可以对Set集合中的元素进行排序(默认按ASCII编码)。
                    4. hashSet()
                      1. hashSet如何保证元素的唯一性?
                        • 通过调用元素的hashCode()方法和equals()方法来完成。如果元素的hashCode值相同,就接着判断equals()方法。如果都相同,则不会把重复的元素存进集合。(只有在hashCode的值相同的时候才会调用equasl方法进行比较。)
                        • 在尽力hashSet集合时,一般都要复写hashCode()和equals()方法,建立自己特有的比较方式,来提高工作效率。并且在复写hashCode()方法时,得保证hash值的唯一性。
                      2. 对于判断元素是否存在以及删除等操作,依赖的方法是元素的hashCode()和equals()方法。
                    5. TreeSet()
                      • 可以对Set集合中的元素进行排序(默认是按字母的ASCII码的顺序)。
                      1. 原理:当每次存进一个元素的时候,该集合对象就会自动调用该元素的compareTo()方法,将这个元素与已有的元素进行比较。通过返回的值将元素通过二叉树的结构进行存放。
                      2. TreeSet的排序
                        1. TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法。也种方式也成为元素的自然顺序,或者叫做默认顺序。
                        2. 示例:
                          class TreeSetDemo 
                          {
                          	public static void main(String[] args) 
                          	{
                          		TreeSet ts = new TreeSet();
                          
                          		ts.add(new Student("lisi02",22));
                          		ts.add(new Student("lisi007",20));
                          		ts.add(new Student("lisi09",19));
                          		ts.add(new Student("lisi08",19));
                          
                          		Iterator it = ts.iterator();
                          		while(it.hasNext())
                          		{
                          			Student stu = (Student)it.next();
                          			System.out.println(stu.getName()+"..."+stu.getAge());
                          		}
                          	}
                          }
                          
                          class Student implements Comparable//该接口强制让学生具备比较性。
                          {
                          	private String name;
                          	private int age;
                          
                          	Student(String name,int age)
                          	{
                          		this.name = name;
                          		this.age = age;
                          	}
                          
                          	public int compareTo(Object obj)//覆盖compareTo方法,建立自己的比较方式。
                          	{
                          
                          		if(!(obj instanceof Student))
                          			throw new RuntimeException("不是学生对象");
                          		Student s = (Student)obj;
                          
                          		System.out.println(this.name+"....compareto....."+s.name);
                          		if(this.age>s.age)
                          			return 1;
                          		if(this.age==s.age)
                          		{
                          			return this.name.compareTo(s.name);
                          		}
                          		return -1;
                          	}
                          
                          	public String getName()
                          	{
                          		return name;
                          	}
                          	public int getAge()
                          	{
                          		return age;
                          	}
                          }

                        3. TreeSet的第二种排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性,在集合初始化时,就有了比较方式。当两种排序都存在时,以比较器为主。比较器的建立   定义一个类,实现Comparator接口,覆盖compare方法。
                        4. 示例:
                          class Student implements Comparable//该接口强制让学生具备比较性。
                          {
                          	private String name;
                          	private int age;
                          
                          	Student(String name,int age)
                          	{
                          		this.name = name;
                          		this.age = age;
                          	}
                          
                          	public int compareTo(Object obj)
                          	{	
                          		if(!(obj instanceof Student))
                          			throw new RuntimeException("不是学生对象");
                          		Student s = (Student)obj;
                          
                          		if(this.age>s.age)
                          			return 1;
                          		if(this.age==s.age)
                          		{
                          			return this.name.compareTo(s.name);
                          		}
                          		return -1;
                          	}
                          
                          	public String getName()
                          	{
                          		return name;
                          	}
                          	public int getAge()
                          	{
                          		return age;
                          	}
                          }
                          class TreeSetDemo2 
                          {
                          	public static void main(String[] args) 
                          	{
                          		TreeSet ts = new TreeSet();
                          
                          		ts.add(new Student("lisi02",22));
                          		ts.add(new Student("lisi02",21));
                          		ts.add(new Student("lisi007",20));
                          		ts.add(new Student("lisi09",19));
                          		ts.add(new Student("lisi06",18));
                          		ts.add(new Student("lisi06",18));
                          		ts.add(new Student("lisi007",29));
                          
                          		Iterator it = ts.iterator();
                          		while(it.hasNext())
                          		{
                          			Student stu = (Student)it.next();
                          			System.out.println(stu.getName()+"..."+stu.getAge());
                          		}
                          	}
                          }
                          
                          class MyCompare implements Comparator	//定义比较器  实现Compare接口
                          {
                          	public int compare(Object o1,Object o2)
                          	{
                          		Student s1 = (Student)o1;
                          		Student s2 = (Student)o2;
                          
                          		int num = s1.getName().compareTo(s2.getName());
                          		if(num==0)
                          		{
                          			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
                          		}	
                          		return num;
                          	}
                          }

                      3. TreeSet排序的另外一种方式:在构造集合的时候向集合中传入一个“比较器实体”。
                        1. 应用场合:当元素自身不具备比较性时,或者具备的比较性不是所需要的。
                        2. 比较器的定义:定义一个类实现Comparator接口,覆盖其中的compare()方法。compare()方法中定义的是比较的内容。
                        3. 当集合中的元素和集合都有比较的功能的时候,输出的结果是按照集合的比较方式排序的。
                        4. 示例:
                          1. import java.util.*;	//导入包
                            class Student implements Comparable	//定义学生类,并且让其具有比较性
                            {
                            	private int age;
                            	private String name;
                            	private String id;
                            
                            	Student(String name,int age,String id)
                            	{
                            		this.name = name;
                            		this.age = age;
                            		this.id = id;
                            	}
                            
                            	public int compareTo(Object obj)
                            	{
                            		if (!(obj instanceof Student))
                            			throw new RuntimeException("不是学生对象");
                            		else
                            		{
                            			System.out.println(this.getName()+"       "+this.getAge());
                            			Student s = (Student) obj;
                            			if(this.age != s.age)
                            			    return this.age - s.age;
                            			else if(this.name != s.name)
                            				return this.name.compareTo(s.name);
                            			return this.id.compareTo(s.id);
                            		}
                            
                            	}
                            	
                            	public String getName()
                            	{
                            		return(this.name);
                            	}
                            	
                            	public int getAge()
                            	{
                            		return(this.age);
                            	}
                            
                            	public String getId()
                            	{
                            		return(this.id);
                            	}
                            }
                            
                            class MyCompartor implements Comparator	//定义一个比较器
                            {
                            	public int compare(Object obj1,Object obj2)
                            	{
                            		if (!(obj1 instanceof Student)&&(obj2 instanceof Student))
                            			throw new RuntimeException(obj1+"and"+obj2+"中有对象不是学生类");
                            		else
                            		{
                            			Student stu1 = (Student) obj1;
                            			Student stu2 = (Student) obj2;
                            
                            			int num1 = new Integer(stu1.getName().length()).compareTo(new Integer(stu2.getName().length()));
                            			if (num1 == 0)
                            			{
                            				int num2 = new Integer(stu1.getAge()).compareTo(new Integer(stu2.getAge()));
                            				if(num2 == 0)
                            				{
                            					return new String(stu1.getId()).compareTo(new String(stu2.getId()));
                            				}
                            				return num2;
                            			}
                            			return num1;
                            		}
                            	}
                            }
                            class MyTreeSet
                            {
                            	public static void main(String[] args) 
                            	{
                            		TreeSet ts = new TreeSet(new MyCompartor());
                            		ts.add(new Student("Zhang,Honemi",23,"520"));
                            		ts.add(new Student("Zhang,Honemi",22,"520"));
                            		ts.add(new Student("Zhang,Honemi",25,"520"));
                            		ts.add(new Student("Zhang,Honemi",23,"521"));
                            		ts.add(new Student("Zhang,Honemix",23,"520"));
                            
                            		for (Iterator it = ts.iterator();it.hasNext() ; )
                            		{
                            			Student stu = (Student)it.next();
                            			System.out.println(stu.getName()+"……"+stu.getAge()+"……"+stu.getId());
                            		}
                            	}
                            }


                        Map接口极其子类

                        Map接口(Map(Key,Value))是实现键-值映射数据结构的一个框架,可以用于存储通过键-值引用的对象。映射与集合有明显的区别,映射中的每个对象都是成对存在的。映射中存贮的每个对象都是通过一个键(key)对象来获取值(value)对象,键值的作用相当于数组中的索引,每一个键值都是唯一的(一个值只能对应一个键),可以利用键值来存贮数据结构中指定位置上的数据。这种存取不由键对象本身决定,而是通过一种散列技术进行处理,从而产生一个被称做散列码的整数值。散列码通常是一个偏置量,它相当于分派给映射的存贮去的起始位置。理想情况下,通过散列技术得到的散列码应该是在给定范围内均匀分布的整数值,并且每个键对象都应该得到不同的散列码。

                        1. Map接口中定义的常用方法
                          1. 添加
                            • V put(K key,Value v):向指定集合中添加指定的键-值映射关系。返回该键值之前对应的Value值。
                            • void putAll(Map<? extends K,? extends V> m ):从指定映射中将所有映射关系复制到此映射中
                          2. 删除
                            • void clear():移除集合中的所有的映射关系。
                            • V remove(Object key):如果存在指定的键对象,则移除该键对象的映射关系,并返回与该键对应的Value的值。
                          3. 判断
                            • boolean containsKey(Object key):如果存在指定的键的映射关系,则返回true,否则返回false
                            • boolean containsValue(Object Value):如果存在指定值的映射关系,则返回true,否则返回false
                            • boolean equals(Object o)用来查看指定的对象与该对象是否为同一个对象,是同一个对象返回true,否则返回false
                            • boolean isEmpty():判断该集合是否存在键-值映射。如果不存在,返回true
                          4. 获取
                            • V get(Object key):如果存在指定的键对象,则返回与该键对象对应的值对象,否则返回null
                            • int hashCode():返回此映射的哈希码值
                            • int size():获得该集合中键-值映射关系的个数。
                            • Collection<V> values():返回此映射中包含的值的Collection视图。
                            •  entrySet()
                            • keySet()
                          5. 常见方法演示
                            • import java.util.*;
                              class MyMap 
                              {
                              	public static void main(String[] args) 
                              	{
                              		Map<String,String> mymap = new HashMap<String,String>();//定义一个Map集合
                              		//向集合中添加元素
                              		/*
                              		1.通过put方法存元素的时候,返回值是该键之前对应的值
                              		2.在HashMap中null可以当作键值或者Value值存在。
                              		*/
                              		sop(mymap.put("01","Zhanghongmei"));
                              		sop(mymap.put("01","Zhanghongmei1"));
                              		mymap.put("02","ZHM");
                              		mymap.put("03","meimei");
                              		mymap.put("04",null);
                              		mymap.put(null,"MM");
                              		
                              		//判断集合中是否存在指定键或者指定值
                              		sop("mymap是否存在键值03:"+mymap.containsKey("03"));
                              		sop("mymap是否存在值ZHM:"+mymap.containsValue("ZHM"));
                              		sop("mymapz中是否存在键值003:"+mymap.containsKey("003"));
                              		sop("mymap中是否存在值ZHMx:"+mymap.containsValue("ZHMx"));
                              		
                              		//通过values方法,把集合中value值,取出。并存储在一个Collection集合中,返回该集合。
                              		sop("mymap中所有的值是:"+mymap.values());
                              	}
                              
                              	public static<E> void sop(E e)
                              	{
                              		System.out.println(e);
                              	}
                              }
                              /*
                              运行结果
                              ===================================
                              null
                              Zhanghongmei
                              mymap是否存在键值03:true
                              mymap是否存在值ZHM:true
                              mymapz中是否存在键值003:false
                              mymap中是否存在值ZHMx:false
                              mymap中所有的值是:[MM, null, Zhanghongmei1, ZHM, meimei]
                              ===================================
                              */


                          6. Map集合的两种取出方式:
                            1. keySet():
                              1. 思想:将Map集合中所有的键存入Set集合,再通过Set集合的迭代器,取出所有的键值,最后通过get(Object key)方法取出所有的Value值。
                              2. 代码示例:
                                import java.util.*;
                                class MyMap1 
                                {
                                	public static void main(String[] args) 
                                	{
                                		Map<String,String> mymap = new HashMap<String,String>();
                                
                                		//存入元素
                                		mymap.put("01","Zhang");
                                		mymap.put("02","Hong");
                                		mymap.put("03","Mei");
                                		
                                		//通过keySet方法取出键值
                                		Set<String> se = mymap.keySet();
                                
                                		//获取Set集合的迭代器
                                		for(Iterator<String> it = se.iterator();it.hasNext();)
                                		{
                                			String key = it.next();
                                
                                			//通过Map集合的get方法取出对应的value的值
                                			String value = mymap.get(key);
                                
                                			sop(key+"="+value);
                                		}		
                                	}
                                
                                	public static<E> void sop(E e)
                                	{
                                		System.out.println(e);
                                	}
                                }
                                /*
                                运行结果
                                ==============================
                                01=Zhang
                                02=Hong
                                03=Mei
                                ==============================
                                */

                            2. Set<Map.Entry<k,v>> entrySet():
                              1. Map.Entry是一个接口里面有5个方法。
                                • boolean equals(Object o) :比较指定对象与此项的相等性。
                                • K getKey() :返回与此项对应的键。
                                • V getValue() :返回与此项对应的值
                                • int hashCode() :返回此映射项的哈希码值
                                • V setValue(V value) :用指定的值替换与此项对应的值。
                              2. 思想:将集合的通过调用entrySet()方法,将该集合内的所有元素的映射关系取出,并存进一个Set集合中,并返回这个集合。通过迭代器依次取出这种关系Map.Entry,然后调用Map.Entry里面的方法可以取出key值和value值,还可以替换value值。
                              3. 代码示例:
                                import java.util.*;
                                class MyMap2 
                                {
                                	public static void main(String[] args) 
                                	{
                                		//建立一个Map集合
                                		Map<String,String> mymap = new HashMap<String,String>();
                                		
                                		//向Map集合中添加元素
                                		mymap.put("02","-zhangsan2");
                                		mymap.put("03","-zhangsan3");
                                		mymap.put("01","-zhangsan1");
                                		mymap.put("04","-zhangsan4");
                                		
                                		//将Map集合中的关系通过entrySet方法取出,存放在Set集合中
                                		Set<Map.Entry<String,String>> se = mymap.entrySet();
                                
                                		//通过迭代器一次取出这种关系
                                		for (Iterator<Map.Entry<String,String>> it = se.iterator();it.hasNext() ; )
                                		{
                                			Map.Entry<String,String> re = it.next();
                                
                                			//通过Map.Entry的方法取出key和value值
                                			String key = re.getKey();
                                			String value = re.getValue();
                                			sop(key+"="+value);
                                		}
                                	}
                                
                                	public static<E> void sop(E e)
                                	{
                                		System.out.println(e);
                                	}
                                }
                                /*
                                运行结果
                                ==================================
                                04=-zhangsan4
                                01=-zhangsan1
                                02=-zhangsan2
                                03=-zhangsan3
                                ==================================
                                */

                        2. Map接口的实现子类
                          1. Hashtable
                            1. 特点:
                              • 此类实现一个哈希表,底层是哈希表数据接口该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。
                              • 为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和equals 方法。
                              • 出现在1.0版本,线程是同步的。
                          2. HashMap
                            1. 特点:
                              • 底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。除了非同步和允许使用 null 之外,HashMap 类与Hashtable 大致相同。
                          3. TreeMap
                            1. 特点:
                              • 底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
                              • 和Set很像,Set底层就是使用了Map集合。
                      • 0
                        点赞
                      • 1
                        收藏
                        觉得还不错? 一键收藏
                      • 0
                        评论
                      评论
                      添加红包

                      请填写红包祝福语或标题

                      红包个数最小为10个

                      红包金额最低5元

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

                      抵扣说明:

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

                      余额充值