码迷,mamicode.com
首页 > 其他好文 > 详细

黑马程序员——黑马基础——Map,集合框架工具类Conlections和Arrays

时间:2015-04-23 13:26:42      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:map

黑马程序员——黑马基础——Map,集合框架工具类Conlections和Arrays

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一,Map集合

Map<K,V>集合是一个接口,和List集合及Set集合不同的是,它是双列集合,并且可以给对象加上名字,即键(Key)。

特点:

        1)该集合存储键值对,一对一对往里存

        2)要保证键的唯一性。

Map集合的子类

        Map

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

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

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

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

Map集合的常用方法

1、添加

        Vput(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。

        voidputAll(Map <? extends K,? extends V> m);//添加一个集合

2、删除

        clear();//清空

        Vremove(Object key);//删除指定键值对

3、判断

        containsKey(Objectkey);//判断键是否存在

        containsValue(Objectvalue)//判断值是否存在

        isEmpty();//判断是否为空

4、获取

        Vget(Object key);//通过键获取对应的值

        size();//获取集合的长度

        Collection<V>value();//获取Map集合中所以得值,返回一个Collection集合

还有两个取出方法,接下来会逐个讲解:

        Set<Map.Entry<K,V>>entrySet();

        Set<K>  keySet();

注:HashMap集合可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。

import java.util.*;
class  MapDemo
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		//添加元素,添加元素,如果出现添加时,相同的键。那么后添加的值会覆盖原有键对应值。
		//并put方法会返回被覆盖的值。
		System.out.println("put:"+map.put("01","zhangsan1"));
		System.out.println("put:"+map.put("01","wnagwu"));
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");

		System.out.println("containsKey:"+map.containsKey("022"));
		//System.out.println("remove:"+map.remove("02"));

		System.out.println("get:"+map.get("023"));

		map.put("04",null);
		System.out.println("get:"+map.get("04"));
		//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
		//获取map集合中所有的值。
		Collection<String> coll = map.values();
		System.out.println(coll);
		System.out.println(map);
	}
}

map集合的两种取出方式:
1,Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。
所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
 Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。


2,Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,
而这个关系的数据类型就是:Map.Entry,Entry其实就是Map中的一个static内部接口。
为什么要定义在内部呢?
因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物。而且该事物在直接访问Map集合中的元素。

class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("01","zhangsan1");
		map.put("04","zhangsan4");

		//将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+":"+value);
		}
		/*
		//先获取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集合:

当量数据之间存在着映射关系的时候,就应该想到使用Map集合。

应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。

示例一:

import java.util.*;

class Student
{
	private String id;
	private String name;
	Student(String id,String name)
	{
		this.id = id;
		this.name = name;
	}
	public String toString()
	{
		return id+":::"+name;
	}
}
class  MapDemo
{
	public static void demo()
	{
		HashMap<String,List<Student>> czbk = new HashMap<String,List<Student>>();

		List<Student> reyu = new ArrayList<Student>();
		List<Student> jiuye = new ArrayList<Student>();

		czbk.put("yureban",reyu);
		czbk.put("jiuyeban",jiuye);

		reyu.add(new Student("01","zhagnsa"));
		reyu.add(new Student("04","wangwu"));
		jiuye.add(new Student("01","zhouqi"));
		jiuye.add(new Student("02","zhaoli"));

		Iterator<String> it = czbk.keySet().iterator();

		while(it.hasNext())
		{
			String roomName = it.next();
			List<Student> room = czbk.get(roomName);
			
			System.out.println(roomName);
			getInfos(room);
		}
	}
	public static void getInfos(List<Student> list)
	{
		Iterator<Student> it = list.iterator();
		while(it.hasNext())
		{
			Student s = it.next();
			System.out.println(s);
		}
	}
	public static void main(String[] args) 
	{
		 demo();
		/*
		HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();

		HashMap<String,String> yure = new HashMap<String,String>();
		HashMap<String,String> jiuye = new HashMap<String,String>();
		czbk.put("yureban",yure);
		czbk.put("jiuyeban",jiuye);

		yure.put("01","zhagnsan");
		yure.put("02","lisi");

		jiuye.put("01","zhaoliu");
		jiuye.put("02","wangwu");

		//遍历czbk集合。获取所有的教室。
		Iterator<String> it = czbk.keySet().iterator();
		while(it.hasNext())
		{
			String roomName = it.next();
			HashMap<String,String> room = czbk.get(roomName);
			
			System.out.println(roomName);
			getStudentInfo(room);
		}
		getStudentInfo(jiuye);
		getStudentInfo(yure);
*/
	}
	public static void getStudentInfo(HashMap<String,String> roomMap)
	{
		Iterator<String> it = roomMap.keySet().iterator();

		while(it.hasNext())
		{
			String id = it.next();
			String name = roomMap.get(id);
			System.out.println(id+":"+name);
		}
	}
}

练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2).....

/*
注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。

什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。

思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3,遍历字符数组。
	将每一个字母作为键去查map集合。
	如果返回null,将该字母和1存入到map集合中。
	如果返回不是null,说明该字母在map集合已经存在并有对应次数。
	那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。

4,将map集合中的数据变成指定的字符串形式返回。
*/
import java.util.*;
class  MapTest3
{
	public static void main(String[] args) 
	{
		String s= charCount("ak+abAf1c,dCkaAbc-defa");
		System.out.println(s);
	}
	public static String charCount(String str)
	{
		char[] chs = str.toCharArray();
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		int count = 0;
		for(int x=0; x<chs.length; x++)
		{
			if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z'))
				continue;
			Integer value = tm.get(chs[x]);
			if(value!=null)
				count = value;
			count++;
			tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。
			count = 0;
			/*
			if(value==null)
			{
				tm.put(chs[x],1);
			}
			else
			{
				value = value + 1;
				tm.put(chs[x],value);
			}
			*/
		}
		//System.out.println(tm);

		StringBuilder sb = new StringBuilder();
		Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
		Iterator<Map.Entry<Character,Integer>>  it = entrySet.iterator();
		while(it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character ch = me.getKey();
			Integer value = me.getValue();
			sb.append(ch+"("+value+")");
		}
		return sb.toString();
	}
}

Collections

Collections是对集合框架的一个工具类。它里边的方法都是静态的,不需要创建对象。并未封装特有数据。

 在Collections工具类中大部分方法是用于对List集合进行操作的,如比较,二分查找,随机排序等。

集合框架的工具类。
Collections:集合框架的工具类。里面定义的都是静态方法。

Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
     List:对元素都有定义索引。有序的。可以重复元素。
    Set:不可以重复元素。无序。

Collections是集合框架中的一个工具类。该类中的方法都是静态的
提供的方法中有可以对list集合进行排序,二分查找等方法。
通常常用的集合都是线程不安全的。因为要提高效率。
如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

import java.util.*;
class  CollectionsDemo
{
	public static void main(String[] args) 
	{
		sortDemo();

	}
	public static void binarySearchDemo()
	{
		List<String> list = new ArrayList<String>();

		list.add("abcd");
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		Collections.sort(list,new StrLenComparator());
		sop(list);

		//int index = Collections.binarySearch(list,"aaaa");
		//int index = halfSearch(list,"cc");
		int index = halfSearch2(list,"aaaa",new StrLenComparator());
		sop("index="+index);
	}
	public static int halfSearch(List<String> list,String key)
	{
		int max,min,mid;
		max = list.size()-1;
		min = 0;
		while(min<=max)
		{
			mid = (max+min)>>1;//  /2;

			String str = list.get(mid);

			int num = str.compareTo(key);
			if(num>0)
				max = mid -1;
			else if(num<0)
				min = mid + 1;
			else
				return mid;
		}
		return -min-1;
	}
	public static int halfSearch2(List<String> list,String key,Comparator<String> cmp)
	{
		int max,min,mid;
		max = list.size()-1;
		min = 0;
		while(min<=max)
		{
			mid = (max+min)>>1;//  /2;

			String str = list.get(mid);

			int num = cmp.compare(str,key);
			if(num>0)
				max = mid -1;
			else if(num<0)
				min = mid + 1;
			else
				return mid;
		}
		return -min-1;
	}

	public static void maxDemo()
	{
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		Collections.sort(list);
		sop(list);
		String max = Collections.max(list/*,new StrLenComparator()*/);
		sop("max="+max);
	}
	public static void sortDemo()
	{
		List<String> list = new ArrayList<String>();

		list.add("abcd");
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		
		sop(list);

		//Collections.sort(list);
		Collections.sort(list,new StrLenComparator());
		//Collections.swap(list,1,2);
		sop(list);
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}<pre class="java" name="code">class StrLenComparator implements Comparator<String>
{
	public int compare(String s1,String s2)
	{
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
	}
}

集合变数组。
Collection接口中的toArray方法。

<T> T[]toArray(T[] a);将集合变为指定类型的数组。
示例二:

import java.util.*;
class  CollectionToArray
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
		/*
		1,指定类型的数组到底要定义多长呢?
		当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
		当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
		所以创建一个刚刚好的数组最优。
		
		2,为什么要将集合变数组?
		为了限定对元素的操作。不需要进行增删了。
		*/
		String[] arr = al.toArray(new String[al.size()]);
		System.out.println(Arrays.toString(arr));
	}
}

Arrays

Arrays是用于操作数组的工具类。里边的方法也全是静态的。不需要创建对象。

把数组变成List集合的好处:可以使用集合的思想和方法来操作数组中的元素。如:contains,get,indexOf,subList等方法。
常见方法

1、Lsit<T> asList(T... a);//将数组转换为集合

注意:

        a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。

        b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。

        c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

2、binarySearch():二分查找方法,fill():替换方法,sort():排序方法等

       特点:可对数组元素进行相应操作,可以接受除boolean之外的其他各种基本数据类型及有序的引用类型数组的参数,且还可以对指定元素的范围,并可根据指定比较器进行相应的操作。

       如:sort(T[]a,Comparator<? super T> c)

                fill(int[]a,int from,int to)等

3、String toString();//可以接收各种数组类型参数,并返回指定数组内容的字符串表现形式。
示例:

<span style="font-size:14px;">class  ArraysDemo
{
	public static void main(String[] args) 
	{
//		int[] arr = {2,4,5};
//
//		System.out.println(Arrays.toString(arr));

		String[] arr = {"abc","cc","kkkk"};

		//把数组变成list集合有什么好处?
		List<String> list = Arrays.asList(arr);
		//sop("contains:"+list.contains("cc"));
		//list.add("qq");//UnsupportedOperationException,

		//sop(list);

		//int[] nums = {2,4,5};
		Integer[] nums = {2,4,5};
		List<Integer> li = Arrays.asList(nums);
		sop(li);
	}
	public static boolean myContains(String[] arr,String key)
	{
		for(int x=0;x<arr.length; x++)
		{
			if(arr[x].equals(key))
				return true;
		}
		return false;
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
</span>



















黑马程序员——黑马基础——Map,集合框架工具类Conlections和Arrays

标签:map

原文地址:http://blog.csdn.net/wk843620202/article/details/45218749

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!