黑马程序员--集合

--------------android培训java培训、学习型技术博客、期待与您交流! --------------


 

1)集合概述

                 作用:

                         面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式.

                   数组和集合区别:

                        集合:
                                  长度可以改变
                                  可以存储不同类型的对象
                                   只能存储对象类型
                        数组:
                                  长度固定
                                  只能存储同一种类型的元素
                                  可以存储基本类型,也可以存储对象类型

2)集合体系

collection

      List     元素有序(存储和取出的顺序一致),元素可以重复

    |--ArrayList    底层数据结构是数组,查询快,增删慢,线程不安全,效率高
    |--Vector        底层数据结构是数组,查询快,增删慢,线程安全,效率低
    |--LinkedList  底层数据结构是链表,查询慢,增删快,线程不安全,效率高

       Set  元素无序(存储和取出顺序不一致),唯一。

                  |--HashSet   底层数据结构是哈希表。依次调用hashCode()和equals()保证元素的唯一性

                                   |--LinkedHashSet   底层数据结构是哈希表和链表。哈希表保证元素的唯一,链表保证元素的有序。

                |--TreeSet  底层数据结构是二叉树。根据自然排序或者比较器的返回值是否是0,决定唯一性和排序         

    TreeSet 自然排序:让被添加到集合中的元素的类实现Comparable接口。
 
	public class Student implements Comparable<Student>
	{
		public int compareTo(Student s)
		{
			...
		}
	}

     TreeSet  比较器排序: 让TreeSet集合在实例化的时候,接收一个Comparator类型的参数。
TreeSet ts = new TreeSet<Student>(new Comparator<Student>(){
		public int compare(Student s1, Student s2)
		{
			...
		} 
	});

枚举:

        就是Vector特有的取出方式。Vector有三种取出方式。

        其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。

特有方法:

         addElement(obj);//添加元素,相当于add(obj);

         Enumerationelements();//Vector特有取出方式(枚举)

         hasMoreElements();//相当于IteratorhasNext()方法

         nextElements();//相当于Iteratornext()方法

代码示例

Vector v=new Vector();  
    for(Enumeration e=v.elements();e.hasMoreElements();)  
{  
    System.out.println(e.nextElements());  
} 
HashSet集合存储自定义对象并遍历代码示例:
姓名和年龄相同为同一个人,重复元素。去除重复元素
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo
{
	public static void main(String[] args){
		//创建集合对象
		HashSet<Student> has = new HashSet<Student>();
		//创建元素对象
		Student s1 = new Student("布兰妮",30,"纽约");
		Student s2 = new Student("布莱曼",39,"伦敦");
		Student s3 = new Student("章子怡",32,"北京");
		Student s4 = new Student("章子怡",32,"北京");
		//添加元素对象到集合中
		has.add(s1);
		has.add(s2);
		has.add(s3);
		has.add(s4);
		//遍历集合---迭代器
		Iterator<Student> it = has.iterator();
		while (it.hasNext())
		{
			Student s = it.next();
			System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getAddress());
		}
		System.out.println("*******************************************");
		//变量集合---增强for循环
		for (Student s : has )
		{
			System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getAddress());
		}		
	}
}

public class Student
{
	private String name;
	private int age;
	private String address;
	public Student(){
	
	}
	public Student(String name, int age, String address){
		this.name = name;
		this.age = age;
		this.address = address;
	}
	public void setName(String name){
		this.name = name;

	}
	public String getName(){
		return name;
	}
	public void setAge(int age ){
		this.age = age;
	}
	public int getAge(){
		return age;
	}
	public void setAddress(String address){
		this.address = address;
	}
	public String getAddress(){
		return address;
	}
         //生成哈希code
	public int hashCode(){
		return this.name.hashCode()+this.age*17+this.address.hashCode();
	}
	public boolean equals(Object obj){
		//提高效率
		if (this == obj)
			return true;
		//健壮性
		if (!(obj instanceof Student))
		{
			return false;
		}
		//转型
		Student s = (Student)obj;
		return this.name.equals(s.name) && this.age == s.age && this.address.equals(s.address);
	}
}


 TreeSet自然排序代码举例:  

/*
 * java.lang.ClassCastException: 
 * cn.itcast_03.Student cannot be cast to java.lang.Comparable
 * 
 * 通过查看API,我们发现了这个接口就是对类进行自然排序的功能定义,我们自己定义的类必须去实现这个接口,才能进行自然排序。
 */
public class Student implements Comparable<Student> {
	// 姓名
	private String name;
	// 年龄
	private int age;

	public Student() {
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int compareTo(Student s) {
		// 根据年龄的大小返回。
		// 如果返回正数:说明大往后放
		// 如果返回负数:说明小往前放
		// return this.age - s.age;
		// 很多时候,我们不仅仅要考虑到主要条件,
		// 还需要考虑次要条件:也就是说在年龄相同的情况下,我们还需要判断姓名是否相同。
		int num = this.age - s.age;
		int num2 = (num == 0) ? this.name.compareTo(s.name) : num;
		return num2;
	}
}

import java.util.Iterator;
import java.util.TreeSet;

/*
 * 需求:存储5个学生,要求按照学生的年龄排序,如果一个对象的成员变量的值都相同即为同一个对象。
 * 
 * 类要进行排序的自然接口:Comparable
 * 
 * TreeSet的底层数据结构是:二叉树。
 * 怎么保证元素的唯一性?
 * 		根据compareTo()方法的返回值是否是0。
 * 			如果是0:说明元素已经存在。
 * 			如果不是0:说明元素不存在。
 * 以及怎么实现数据的排序 ?
 * 			如果compareTo()方法的返回值是一个正数:说明添加的元素,比以前的那个元素大。
 * 			如果compareTo()方法的返回值是一个负数:说明添加的元素,比以前的那个元素小。
 * 
 * 			如果数据较大,就往后放。
 * 			如果数据较小,就往前放。
 * 最后,遍历即可。
 */
public class TreeSetDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		TreeSet<Student> ts = new TreeSet<Student>();

		// 创建元素对象
		Student s1 = new Student("linqingxia", 26);
		Student s2 = new Student("wangzuxian", 40);
		Student s3 = new Student("yangmi", 20);
		Student s4 = new Student("zhaowei", 38);
		Student s5 = new Student("linqingxia", 26);
		Student s6 = new Student("linen", 26);

		// 添加学生
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);

		// 遍历数据
		Iterator<Student> it = ts.iterator();
		while (it.hasNext()) {
			Student s = it.next();
			System.out.println(s.getName() + "***" + s.getAge());
		}
	}
}

TreeSet比较器排序代码举例:

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

/*
 * 需求:要求存储学生,按照学生的姓名长度排序。(排序)
 * 		  如果成员变量的值都相同即为同一个值。(唯一)
 * 
 * 编程信条:对修改关闭,对扩展开放。
 * 
 * 如果两者同时都存在,以比较器的方式为主。
 * 
 * 格式:
 * 		new 类名或者接口名()
 * 		{
 * 			//重写方法
 * 		}
 * 
 * 		一般当方法的参数是接口,并且接口中的方法不超过3个的时候,
 * 		我们就会采用匿名内部类的形式去体现。
 * 		
 * 		这种格式体现的是一个:
 * 			是一个实现了指定接口的子类的匿名对象。
 * 		
 */
public class TreeSetDemo {
	public static void main(String[] args) {
		// 创建集合对象
		// TreeSet<Student> ts = new TreeSet<Student>();
		// TreeSet(Comparator comparator)
		// 不管是在调用成员方法时,还是在调用构造方法时,
		// 如果你看到的参数是抽象类或者接口
		// 请注意:这里传递肯定是一个具体的实现类对象。
		// MyComparator my = new MyComparator();
		// MyComparator2 my2 = new MyComparator2();
		// TreeSet<Student> ts = new TreeSet<Student>(my2);

		// 如果接口中只有一个方法,一般不在专门创建一个具体的类去做。
		// 用匿名内部类实现。
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				int num = s1.getName().length() - s2.getName().length();
				int num2 = (num == 0) ? s1.getName().compareTo(s2.getName()) : num;
				int num3 = (num2 == 0) ? s1.getAge() - s2.getAge() : num2;
				return num3;
			}
		});

		// 创建元素对象
		Student s1 = new Student("linqingxia", 26);
		Student s2 = new Student("wangzuxian", 40);
		Student s3 = new Student("yangmi", 20);
		Student s4 = new Student("zhaowei", 38);
		Student s5 = new Student("linqingxia", 26);
		Student s6 = new Student("linen", 26);
		Student s7 = new Student("linqingxia", 56);

		// 添加学生
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		ts.add(s7);

		// 遍历数据
		Iterator<Student> it = ts.iterator();
		while (it.hasNext()) {
			Student s = it.next();
			System.out.println(s.getName() + "***" + s.getAge());
		}
	}
}

public class Student implements Comparable<Student> {
	// 姓名
	private String name;
	// 年龄
	private int age;

	public Student() {
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int compareTo(Student s) {
		// 姓名长度
		// 主要条件
		int num = this.name.length() - s.name.length();
		// 次要条件
		int num2 = (num == 0) ? this.name.compareTo(s.name) : num;
		// 当姓名的长度和内容都相同的时候,需要在考虑年龄是否也相同。
		int num3 = (num2 == 0) ? this.age - s.age : num2;
		return num3;
	}
}

map集合

      由键值对形成的一个集合,键是唯一的。值可以重复。      

       Map

                |--Hashtable:底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的。JDK1.0,效率低。

                |--HashMap:底层是哈希表数据结构。允许使用nullnull值,该集合是不同步的。JDK1.2,效率高。

                |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。

              MapSet很像。其实Set底层就是使用了Map集合。

      Map和Collection的区别   

      map:1,Map是键值对形式的集合,数据是成对出现的。2,键是唯一的。

       Collection:1,是单列形式的集合,数据是单一出现的。2,Collection的儿子Set的元素是唯一的。  

      Map集合的两种取出方式   

              aSet<K> keySet():将Map中所以的键存入到Set集合。因为Set具备迭代器。所以可以通过迭代方式取出所以键的值,再通过get方法。获取每一个键对应的值。            

              bSet<Map.Entry<K,V>>   entrySet():将Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry其实,Entry也是一个接口,它是Map接口中的一个内部接口。

keySet方式代码

/* 
每一个学生都有对应的归属地。 
学生Student,地址String。 
学生属性:姓名,年龄。 
注意:姓名和年龄相同的视为同一个学生。 
保证学生的唯一性。 
 
思路:1、描述学生类 
      2、定义一个Map集合,存储学生对象和地址值 
      3、获取Map中的元素 
*/  
  
import java.util.*;  
  
//描述学生类  
class Student implements Comparable<Student>  
{  
    private String name;  
    private int age;  
    Student(String name,int age)  
    {  
        this.name=name;  
        this.age=age;  
    }  
    public String getName()  
    {  
        return name;  
    }  
  
    public int getAge()  
    {  
        return age;  
    }  
  
    //复写hashCode  
    public int hashCode()  
    {  
        return name.hashCode()+age*33;   
    }  
    //复写equals,比较对象内容  
    public boolean equals(Object obj)  
    {  
        if(!(obj instanceof Student))  
            throw new ClassCastException("类型不匹配");  
        Student s=(Student)obj;  
        return this.name.equals(s.name)&&this.age==s.age;  
    }  
  
    //复写compareTo,以年龄为主  
    public int compareTo(Student c)  
    {  
        int num=new Integer(this.age).compareTo(new Integer(c.age));  
        if(num==0)  
        {  
            return this.name.compareTo(c.name);  
        }  
        return num;  
    }  
  
    //复写toString,自定义输出内容  
    public String toString()  
    {  
        return name+"..."+age;  
    }  
  
}  
class  HashMapTest  
{  
    public static void main(String[] args)   
    {  
        HashMap<Student,String > hm=new HashMap<Student,String >();  
        hm.put(new Student("zhangsan",12),"beijing");  
        hm.put(new Student("zhangsan",32),"sahnghai");  
        hm.put(new Student("zhangsan",22),"changsha");  
        hm.put(new Student("zhangsan",62),"USA");  
        hm.put(new Student("zhangsan",12),"tianjing");  
  
        keyset(hm);  
    }  
  
    //keySet取出方式  
    public static void keyset(HashMap<Student,String> hm)  
    {  
        Iterator<Student> it=hm.keySet().iterator();  
  
        while(it.hasNext())  
        {  
            Student s=it.next();  
            String addr=hm.get(s);  
            System.out.println(s+":"+addr);  
        }  
    }  
}  

Map.Entry方式代码

class  HashMapTest  
{  
    public static void main(String[] args)   
    {  
        HashMap<Student,String > hm=new HashMap<Student,String >();  
        hm.put(new Student("zhangsan",12),"beijing");  
        hm.put(new Student("zhangsan",32),"sahnghai");  
        hm.put(new Student("zhangsan",22),"changsha");  
        hm.put(new Student("zhangsan",62),"USA");  
        hm.put(new Student("zhangsan",12),"tianjing");  
  
        entryset(hm);  
    }  
//entrySet取出方式  
    public static void entryset(HashMap<Student,String> hm)  
    {  
        Iterator<Map.Entry<Student,String>> it=hm.entrySet().iterator();  
  
        while(it.hasNext())  
        {  
            Map.Entry<Student,String> me=it.next();  
            Student s=me.getKey();  
            String addr=me.getValue();  
            System.out.println(s+":::"+addr);  
        }  
    }  
}  
Map应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。
/*  
map集合被使用是因为具备映射关系。 
以下是班级对应学生,而学生中学号对应着姓名的映射关系: 
"yureban"   Student("01" "zhangsan"); 
 
"yureban" Student("02" "lisi"); 
 
"jiuyeban" "01" "wangwu"; 
"jiuyeban" "02" "zhaoliu"; 
 
就如同一个学校有多个教室。每一个教室都有名称。 
*/  
import java.util.*;  
  
class  MapExpandKnow  
{  
    public static void main(String[] args)   
    {  
        //预热班集合  
        HashMap<String,String> yureban=new HashMap<String,String>();  
        //就业班集合  
        HashMap<String,String> jiuyeban=new HashMap<String,String>();  
        //学校集合  
HashMap<String,HashMap<String,String>> czbk=new HashMap<String,HashMap<String,String>>();  
          
        //学校中班级集合和名称的映射  
        czbk.put("yureban",yureban);  
        czbk.put("jiuyueban",jiuyeban);  
          
//预热班级中学号与姓名的映射  
        yureban.put("01","zhangsan");  
        yureban.put("02","lisi");  
          
        //就业班级中学号与姓名的映射  
        jiuyeban.put("01","wangwu");  
        jiuyeban.put("02","zhouqi");  
              
            //直接显示全部学生信息  
        getAllStudentInfo(czbk);  
  
    }  
    //定义一个方法获取全部学生信息,包括在哪个班级,叫什么名字,学号多少  
    public static void getAllStudentInfo(HashMap<String ,HashMap<String,String>> hm)  
    {  
        for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; )//用keySet取出方式  
        {  
            String s= it.next();//班级名称  
            System.out.println(s+":");  
            HashMap<String,String> stu=hm.get(s);//班级集合  
  
            getStudentInfo(stu);  
        }  
    }  
      
    //获取班级中学生的信息,包括姓名和学号  
    public static void getStudentInfo(HashMap<String,String> hm)  
    {  
        for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; )  
        {  
            String key=it.next();//学号  
            String value=hm.get(key);//姓名  
            System.out.println(key+"..."+value);  
        }  
    }  
}  




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值