12 集合(下)

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

						集合(下)


1、迭代(iterator):迭代是取出collection集合中元素的方式(for循环、增强for循环、迭代器)。
		     for循环遍历:删除元素时集合后面的元素会向前移动,删除后循环变量要--
		     增强for循环:for(类型 变量名;容器){循环体},每次循环变量指向不同容器中元素
				  不能改变容器的结构。

    Iterable接口:JDK1.5新定义作为Collection的父接口,因为Collection有iterator(),所以每一个子类集合对象
		  都具备迭代器(内部类),直接访问集合内部元素,主要为了实现增强for循环.
		collection c = new ArrayList();	
		for(Interator it = c.iterator();it.hasNext()){
			System.out.println(it.next());
		}
		另一种方式:
		Iterator it = c.iterator();		//通过对象的iterator()获得迭代器Iterator
		while(it.hasNext()) {			//通过迭代器的hasNext()判断是否存在下一个元素
			System.out.println(it.next());	//通过迭代器的next()获取下一个元素
		}

    迭代注意事项:
	迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
	迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
	迭代器的next方法返回值类型是Object,所以要记得类型转换。
	为什么next方法的返回类型是Object的呢?
	      集合是存储对象的容器,而对象可以是任意类型的,所以next()获取的元素都会自动强转为Object类型
	      如果指定了集合的类型,在获取元素时必须要强转为定义的类型。

    迭代出现的问题:
	Iterator it = list.iterator();
	while(it.hasNext()){
		String s = (String)it.next();
		if(s.equals("abc2"))
			list.add("haha");//此处出现并发修改异常:ConcurrentModificationException
			System.out.println("s="+s);
	}
	System.out.println(list);
	Iterator里面没有add(),
	
	原因:迭代器Iterator中只有三个操作,判断hasNext(),获取next(),删除remove()。想要其它的操作时,
	      比如添加,iterator就不可以使用了。该例用容器list当中的add()添加元素,所以出现了异常。
	解决:要么只使用集合的方法操作元素,要么只使用迭代器的方法操作元素,不能同时使用。
	      对于List集合,有一个新的迭代方式:ListIterator(列表迭代器),它是Iterator的子接口,
	      提供了更多迭代过程中对元素的操作:
		List list = new ArrayList();
		ListIterator li = list.listIterator();
		li.add(E e)		//将指定的元素插入列表
		li.set(E e)		//用指定元素替换next 或 previous 返回的最后一个元素
		boolean li.hasNext()	//是否有下一个
		boolean li.hasPrevious()//是否有前一个
		li.next()		//返回下一个元素
		li.previous()		//返回前一个元素


2、Map集合:
    Map集合的特点:
	Map与Collection在集合框架中属并列存在。
	Map存储的是键值对
	Map存储元素使用put方法,Collection使用add方法。
	Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素。
	Map集合中键要保证唯一性。
    
    Map集合的常用方法:
	添加:put(key,value): 如果存入已有的键,会发生值覆盖的情况。   
	判断:containsKey(key),containsValue(value);
	取出:get(key);
	删除:remove(key);
	个数:size();
	取出所有值:values();

    Map集合的两种遍历方式:
	原理:将Map集合转成Set集合。在通过迭代器取出。
	keySet():返回一个由Map集合中的所有键组成的Set集合,再使用Map集合的get()取出键所对应的值。
	entrySet():将Map集合中的键值映射关系封装成Map.Entry对象,并存入到Set集合中。迭代该集合取出
		   Map.Entry对象,并通过该对象的getKey(),getValue()方法取出map集合中的键和值。
    
    Map集合的子类:
	|--TreeMap:对键进行排序,排序原理与TreeSet相同。通过二叉树算法保证键唯一性
	|--HashMap:线程不安全,速度快,允许存放null键,null值。通过HashSet原理保证键唯一性
		    当HashMap返回为null时,有两种情况:该键不存在,或该键存在对应的值是null。
	    |--LinkedHashMap:是HashMap的子类, 原理相同,但是可以保留存储顺序
	|--Hashtable:线程安全,速度慢,不允许存放null键,null值,已被HashMap替代。
	    |--Properties:
		Hashtable的子类,所以也是线程安全的。通常用来操作配置文件,一般配置项等号两边都是String,
		所以该集合中的两列保存的都是String类型的数据。这个集合中只能存String,所以不需要定义泛型。
		是一个可以集合和流相结合的容器。
		特有方法:
		    list(PrintStream):列出集合中的数据。
		    load(InputStream):将输入流关联的文件中的数据加载进集合。
		    store(OutputStream,String):将集合的数据存储到输出流所关联的文件中。
		    setProperties(key,value):只是在内存中修改了配置属性

    什么时候使用Map集合?
	当分析问题时,对象间出现了映射关系时,就要先想到Map集合。
	例:获取字符串中每一个字母出现的次数。要求结果是:a(3)b(1)....;
	public String getCharCount(String str) {
	    char[] chs = str.toCharArray();	//将传入的字符参数转换成字符数组
	    int count = 0;			//定义计数器
	    TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();//定义TreeMap集合存储元素
	    for(int x=0; x<chs.length; x++) {	//从0角标遍历字符数组,角标上的元素是集合中的键
		if(!(chs[x]>='a' && chs[x]<='z'))//如果角标上的键不再a~z之间
		    continue;			//结束本次循环,开始下次循环
		Integer i = tm.get(chs[x]);	//满足条件,通过集合get(key)方法获取对应的值i
		if(i!=null)			//值不为空,这个值就是该字符的次数
		    count = i;			
		count++;			//为空,计数器+1表示该字符出现一次
		tm.put(chs[x],count);		//put(key,value)方法,将字符和对应的次数添加到集合中
	    }
	    StringBuilder sb = new StringBuilder();//定义缓冲区StringBuffer sb
	    Iterator<Map.Entry<Character,Integer>> it = tm.entrySet().iterator();
	    while(it.hasNext()) {		//获取迭代器,定义泛型,类型为Entry:键值对映射关系
		Map.Entry<Character,Integer> me = it.next();//获取集合中的Entry
		Character ch = me.getKey();	//再通过Entry的getKey()方法,获取键
		Integer x = me.getValue();	//getValue()方法获取值
		sb.append(ch+"("+x+")");	//append()方法将键和值添加到缓冲区中
	    }
	    return sb.toString();		//toString()将sb中的元素转成字符串,并返回给函数
	}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值