zoukankan      html  css  js  c++  java
  • java day11第十一课 集合类Collection和Map

    集合类

    面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的方式。
    数组和集合类都是容器,他们有什么不同?

    数组虽然也可以存储对象,但长度是固定的;集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。
    

    集合类的特点:

    集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
    


    注意:每一个容器的存储方式都有不同,这个存储方式称之为:数据结构

    一、Collection

    class Demo{
    	public static void main(String[] args){
    	//创建一个集合容器,使用Collection接口的子类ArrayList
    		ArrayList list = new ArrayList();
    		//添加元素
    		list.add("day01");
    		list.add("day02");
    		list.add("day03");
    		list.add("day04");
    		
    		
    		//打印原集合
    		syso(list);
    		
    		//删除元素day01
    		list.remove("day01");
    		//清空集合
    		list.clear();
    		//判断元素
    		list.contains("day02");//判断list集合里面是否存在day02;
    		list.isEmpty();//判断集合是否为空
    		//获取集合的长度,个数
    		list.size();
    		
    		ArrayList list1 = new ArrayList();
    		list1.add("day02");
    		list1.add("day03");
    		list1.add("day04");
    		list1.add("day05");
    		
    		list.retainAll(list1);//取两个集合的交集,list里面只保留交集。
    		
    	//迭代器:
    		Iterator it = list1.iterator();
    		syso(it.next());// 返回一个元素,从第一个元素开始返回
    		while(it.hasNext()){//获取迭代器,取出集合里面的元素
    		syso(it.next());//循环打印出所有元素
    		
    		}
    		
    		
    		for(Iterator it1 = list1.iterator();it1.hasNext();){
    		syso(it1.next());
    	}
    		
    	}
    public static void syso(Object obj){
    
    	System.out.println(obj);
    }
    }
    

    什么是迭代器?

    其实就是集合的取出元素的方式;我们把取出的方式定义在集合的内部,这样我们取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类;而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容判断和取出。那么刻意将这些共性抽取。(这些内部类都符合规则,该规则是Iterator。通过对外提供的方法:iterator())
    

    Collection中常见的两个接口List 和 Set

    List:元素是有序的,元素可以重复,因为该元素有索引。

    凡是可以操作角标的方法都是该体系的特有方法。

    add(index,element);
    addAll(index,Collection)
    

    remove(index);
    

    set(index,element);
    

    get(index);
    subList(from,to);
    ListIterator();
    

    代码示例:

    class Demo{
    	public static void main(String[] args){
    	//创建一个集合容器,使用Collection接口的子类ArrayList
    		ArrayList list = new ArrayList();
    		//增
    		list.add("day01");
    		list.add("day02");
    		list.add("day03");
    		//在指定位置添加;
    		list.add(1,"day02");//相当于插入
    		//删除指定位置的元素
    		list.remove(2);
    		//修改
    		list.set(2,"改了");
    		//查(通过角标获取元素)
    		list.get(1)
    		//获取所有元素
    		for(int i = 0;i<list.size();i++){
    			System.out.print(list.get(i)+",")
    		}
    		System.out.println();
    		//迭代器获取所有元素
    		Iteractor it = list.iteractor();
    		while(it.hasNext()){
    			System.out.print(it.next()+",")
    		}
    		
    		//通过indexof()获取对象的位置
    		list.indexof("day01");//返回是一个int值
    		List sub = list.subList(1,3);
    		System.out.println(sub);//包含1角标不包含3
    		
    		
    }
    }
    

    列表迭代器:
    List集合特有的迭代器,ListIteractor是Iteractor的子接口。
    在迭代时,不可以通过集合对象的方法,操作集合中的元素,因为回发生集合并发异常,所以在迭代时,只能通过迭代器的方法操作元素。可是Iteractor的方法只能对元素进行判断,取出,删除的操作。如果想要其他的操作如:添加,修改等,就需要使用其子接口,ListIteractor,该接口只能通过List集合的listIteractor方法获取。

    class Demo{
    	public static void main(String[] args){
    	//创建一个集合容器,使用Collection接口的子类ArrayList
    		ArrayList list = new ArrayList();
    		//增
    		list.add("day01");
    		list.add("day02");
    		list.add("day03");
    		Iteractor it = list.iteractor();
    	//		Iteractor it = list.iteractor();
    	//			while(it.hasNext()){
    	//			Object obj = it.next();
    	//			if(obj.equals("day02")){
    	//				//list.add("day007");异常,并发异常
    	//				//只能使用迭代器的方法,如:
    	//				it.remove();
    	//			}
    	//		
    	//		}			
    		ListIterator li = list.listIterator();
    		while(li.hasNext()){
    			Object obj = li.next();
    			if(obj.equals("day02")){
    				li.add("day007");
    				}
    			}
    			
    			//反向从后往前面进行查找判断		
    		while(li.hasPrevious()){
    		syso(li.previous());
    	}
    
    
    }
    }
    

    ArrayList:

    底层的数据结构使用的是数组结构;特点:查询速度很快,但是增删就较慢(针对元素比较多的情况)
    

    linkedList

    底层是链表数据结构。特点:增删掉速度很快,查询的时候较慢
    代码示例:
    import java.util.LinkedList;
    
    public class LinkedListDemo {
    
    public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		LinkedList link  = new LinkedList();
    		//方法:addFirst();从前面开始添加
    		link.addFirst("java01");
    		link.addFirst("java02");
    		link.addFirst("java03");
    		System.out.println(link);
    //		addlast();从后面开始添加元素
    		link.addLast("java04");
    		System.out.println(link);
    //		获取第一个元素;如果没有元素会出现NoSuchElementException异常
    		System.out.println(link.getFirst());
    //		获取最后一个元素
    		System.out.println(link.getLast());
    		
    //		获取第一个元素并删除;如果没有元素会出现NoSuchElementException异常
    		System.out.println(link.removeFirst());
    		System.out.println(link);
    //		获取最后一个元素并删除
    		System.out.println(link.removeLast());
    		System.out.println(link);
    //		JDK1.6出现了替代方法,
    //		从前面开始添加
    		link.offerFirst("java00");
    		System.out.println(link);
    //		从后面开始添加
    		link.offerLast("java04");
    		System.out.println(link);
    //		获取元素,但不删除元素,如果集合中没有元素,会返回null
    		link.peekFirst();
    		System.out.println(link);
    		link.peekLast();
    		System.out.println(link);
    //		获取元素,但是元素被删除,如果集合中没有元素,会返回null
    		link.pollFirst();
    		System.out.println(link);
    		link.pollLast();
    		System.out.println(link);
    		
    }
    
    }
    

    vector

    底层是数组数据结构。和ArrayList一样,区别:线程同步
    代码示例:
    import java.util.Enumeration;
    import java.util.Vector;
    
    public class VoctorDemo {
    
    public static void main(String[] args) {
    	// TODO Auto-generated method stub
    	Vector v = new Vector();
    	
    	v.add("java01");
    	v.add("java02");
    	v.add("java03");
    	v.add("java04");
    	v.add("java05");
    	//枚举是Vector特有的取出方式		
    	Enumeration  en = v.elements();
    	while(en.hasMoreElements()){
    		System.out.println(en.nextElement());
    	}
    	//		枚举和迭代器很像,其实枚举和迭代是一样的,因为枚举的名称和方法都过长,所以被迭代器取代
    
    }
    }	
    

    练习:用ArrayList存储;
    定义一个Person的类,存入ArrayList集合中,去除重复元素,定义:名字相同的和年龄都相同的为重复元素。

    Set:元素是无序(存入和取出的顺序不一定一致)的,元素不可以重复。Set集合的功能和Collection是一致的。它有两个常见的子类:hashSet、TreeSet

    hashSet
    练习hashSet里面方法;

    数据机构是哈希表,线程是非同步的。
    hashSet是通过里面的hashCode和equals方法来完成元素的唯一性,如果哈希值相同,才回判断equlas是否相同,如果哈希值不同,不会调用equlas方法。
    

    练习:用hashSet存储;
    定义一个Person的类,存入hashSet集合中,去除重复元素,定义:名字相同的和年龄都相同的为重复元素。

    HashSet判断和删除
    对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法

    TreeSet

    可以对Set集合里面进行排序; 底层数据是:二叉树,保证元素唯一行的依据。CompareTo方法return 0。
    代码示例:
    public class TreeSetDemo {
    
    public static void main(String[] args) {
    	TreeSet<String> tr = new TreeSet<String>();
    
    	tr.add("cba");
    	tr.add("abcd");
    	tr.add("aaa");
    	tr.add("bca");
    	tr.add("Aca");
    	Iterator<String> it = tr.iterator();
    	while(it.hasNext()){
    		
    		System.out.println(it.next());
    	}
    	//输出:
    	//		Aca
    	//		aaa
    	//		abcd
    	//		bca
    	//		cba
    }
    }
    

    练习:往TreeSet里面存储学生对象,按照学生的年龄进行排序,排序时,当主要条件相同时,一定要判断次要条件

    排序的方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法。也称之为元素的自然顺序,或者也可以称之为默认顺序。
    

    TreeSet集合的第二种比较方式

    当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时,集合需要具备比较性。
    代码示例:
    import java.util.Comparator;
    
    public class MyCompare implements Comparator{
    
    @Override
    public int compare(Object o1, Object o2) {
    	// TODO Auto-generated method stub
    	
    	Student s1 = (Student)o1;
    	Student s2 = (Student)o2;
    	int num = s1.getName().compareTo(s2.getName());//先比较名字
    
    	if(num == 0){//如果名字相等
    		
    		if(s1.getAge() > s2.getAge()){//比较年龄
    			return 1;
    		}else if(s1.getAge() == s2.getAge()){
    			return 0;
    		}
    		return -1;
    	}
    	return num;
    	
    }
    
    
    }
    
    public class TreeSetDemo {
    
    public static void main(String[] args) {
    	TreeSet<Student> tr = new TreeSet<Student>(new MyCompare());
    
    	
    	tr.add(new Student("zhangsan01",40));
    	tr.add(new Student("zhangsan02",21));
    	tr.add(new Student("zhangsan003",22));
    	
    	
    	Iterator<Student> it = tr.iterator();
    	while(it.hasNext()){
    		Student stu = it.next();
    		System.out.println(stu.getName()+"......"+stu.getAge());
    	}
    	
    	
    	}
    
    }	
     两种比较器都存在时,我们都以比较器为准。
    

    练习:按照字符串长度排序,字符串本身具备比较性,但是它的比较方法不是我们所需要的,这时我们需要使用比较器。

    Map

    Map集合:该集合存储键值对,是一对一对的存储,注意:保证键值的唯一性。
    1、添加

    put(K key, V value)
    putAll(Map<? extends K,? extends V> m) 
    

    2、删除

    clear()
    remove(Object key)
    

    3、判断

    containsValue(Object value) 
    containsKey(Object key) 
    isEmpty()
    

    4、获取

    get(Object key) 
    values()
    
    
    entrySet()
    keySet()
    

    Map的三个孩子

    Hashtable  :底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。
    HashMap    :底层是哈希表数据结构,允许存入null键null值,该集合是不同步的
    TreeMap    :底层是二叉树数据结构,线程不同步。可以用于给map集合里面的键进行排序
    代码演示:
    package com.rf.mapDemo;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    public class MapDemo {
    
    public static void main(String[] args) {
    	Map<String,String> map = new HashMap<String,String>();
    //添加元素,如果添加相同的键,那么后添加的值会覆盖原有的键的值,put方法会范围被覆盖的值
    	System.out.println(map.put("01", "zhangsan1"));
    	System.out.println(map.put("01", "zhang"));
    	map.put("02", "zhangsan2");
    	map.put("03", "zhangsan3");
    	System.out.println(map.containsKey("01"));
    	System.out.println(map.remove("02"));
    	System.out.println(map);
    	System.out.println(map.get("03"));
    	//可以通过get方法返回值来判断一个键是否存在,通过返回null来应用
    	map.put("04", null);
    	System.out.println(map.get("04"));
    //	获取map集合中所有的值
    	Collection<String> coll = map.values();
    	System.out.println(coll);
    	System.out.println(map);
    	
    }
    }
    

    map集合中两种取出方式:

    1、keyset:将map中所有的键存入set集合,因为set具备迭代器,所以可以迭代方法取出所有的键,再根据get方法获取每一个键对应的值
    
    package com.rf.mapDemo;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    public class MapDemo1 {
    
    public static void main(String[] args) {
    	// TODO Auto-generated method stub
    
    	Map<String,String> map = new HashMap<String,String>();
    	map.put("01", "zhangsan1");
    	map.put("02", "zhangsan2");
    	map.put("03", "zhangsan3");
    	map.put("04", "zhangsan4");
    	//先获取map集合的所有键的set集合,keyset()
    	Set<String> keyset = map.keySet();
    	//有了set集合就可以获取其迭代器
    	Iterator<String> it = keyset.iterator();
    	while(it.hasNext()){
    		String key = it.next();
    		//有了键我们就可以通过map集合的get方法获取其对应的值
    		String value = map.get(key);
    		System.out.println("key = "+key+"  value = "+value);
    		
    	}	
    }
    
    }
    

    Map集合的取出原理:将map集合专程set集合,再通过迭代器取出

    2、entrySet() :将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是Map.Entry.其实Entey也是一个接口,它事Map接口中的一个内部接口。
    代码演示:
    package com.rf.mapDemo;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    public class MapDemo1 {
    
    public static void main(String[] args) {
    	// TODO Auto-generated method stub
    
    	Map<String,String> map = new HashMap<String,String>();
    	map.put("01", "zhangsan1");
    	map.put("02", "zhangsan2");
    	map.put("03", "zhangsan3");
    	map.put("04", "zhangsan4");
    //将Map里面的映射关系取出,存入到set集合中
    		Set<Map.Entry<String, String>> enteySet = map.entrySet();
    	
    	Iterator<Map.Entry<String, String>> it = enteySet.iterator();
    	
    	while(it.hasNext()){
    		Map.Entry<String, String> mm = it.next();
    		String key = mm.getKey();
    		String value = mm.getValue();
    		System.out.println(key+"   "+value);
    	}
    

    练习:每一个学生Student都有一个对应的归属地定义为String类型。学生属性:姓名,年龄

    注意:姓名和年龄相同的视为同一个学生。保证学生的唯一性。
    Comparable和Comparator比较

    1、描述学生。

    2、定义Map容器,将学生作为键,地址作为值存入集合中。

    3、获取Map中的元素并进行排序。

    TreeMap:

    public class MapDemo1 {
    
    public static void main(String[] args) {
    	// TODO Auto-generated method stub
    
    	TreeMap<String,String> map = new TreeMap<String,String>();
    	map.put("04", "zhangsan4");
    	map.put("03", "zhangsan3");
    	map.put("01", "zhangsan1");
    	map.put("02", "zhangsan2");
    //		将Map里面的映射关系取出,存入到set集合中
    		Set<Map.Entry<String, String>> enteySet = map.entrySet();
    	
    	Iterator<Map.Entry<String, String>> it = enteySet.iterator();
    	
    	while(it.hasNext()){
    		Map.Entry<String, String> mm = it.next();
    		String key = mm.getKey();
    		String value = mm.getValue();
    		System.out.println(key+"   "+value);
    	}	
    
    }
    }
    

    Map扩展

    map集合被使用是因为具备映射关系
    "进度班"  "01"  "张三"
    "进度班"  "02"  "李四"
    "J1701"  "01"  "王五"
    "J1701"  "02"  "王二"
    此信息中,我们要怎样把上述信息装入集合中,	根据班级信息的到所有的所有信息
  • 相关阅读:
    最小生成树+BFS J
    Noip 2016
    舒适的路线 (code[vs] 1001)
    拦截导弹 (加了神奇的位运算)
    逃出克隆岛 (codevs 2059)
    回家(洛谷 P1592)
    热浪
    城堡
    笔记 (一道正解思路巧妙的题)
    脱水缩合
  • 原文地址:https://www.cnblogs.com/chendujie/p/6838932.html
Copyright © 2011-2022 走看看