API-集合框架-Map、Collections、Arrays

一、Map集合
 
1、Map集合概述
Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
 
Map子类对象
    |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。
    |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。
    |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。
Map和Set很像。其实Set底层就是使用了Map集合。
 
2、Map共性方法
a、添加
        put(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。
        voidputAll(Map <? extends K,? extends V> m);//添加一个集合
b、删除
        clear();//清空
        remove(Object key);//删除指定键值对
c、判断
        containsKey(Objectkey);//判断键是否存在
        containsValue(Objectvalue)//判断值是否存在
        isEmpty();//判断是否为空
d、获取
        get(Object key);//通过键获取对应的值
        size();//获取集合的长度
        values();//获取Map集合中所有的值,返回一个Collection集合
还有两个取出方法,接下来会逐个讲解:
        Set<Map.Entry<K,V>>entrySet();
        Set<K>  keySet();
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">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","wangwu"));
        System.out.println("put:"+map.put("01","zhangsan1"));
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
 
		System.out.println("containsKey:"+map.containsKey("02"));
		System.out.println("remove:"+map.remove("07"));
 
		map.put("08",null);
		System.out.println("get:"+map.get("02"));
		//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
 
		//获取map集合中所有的值
		Collection<String> coll = map.values();
		System.out.println(coll);
		System.out.println(map);
	}
}</span>
 
3、Map集合的两种取出方式 
Map集合的取出原理:将Map集合转成Set集合。再通过迭代器取出。
1、Set<k> keySet():将Map中所有的键存入到Set集合。因为Set具备迭代器。所以可以通过迭代方式取出所有的键,再通过get方法。获取每一个键对应的值。
2、Set<Map.Entry<k,v>> entrySet():将Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class MapDemo1
{
	public static void main(String[] args) 
	{
		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("keySet:key="+key+",value="+value);
		}
		
		//将Map集合中的映射关系取出,存入到Set集合中。
		Set<Map.Entry<String,String>> entryset = map.entrySet();
 
		Iterator<Map.Entry<String,String>> it1 = entryset.iterator();
 
		while(it1.hasNext())
		{
			Map.Entry<String,String> me = it1.next();
			//有了键就可以通过Map集合的get方法获取其对应的值。
			String key = me.getKey();
			String value = me.getValue();
			System.out.println("entrySet:key="+key+",value="+value);
		}
 	}
}</span>
例:将学生按姓名、年龄排序
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/* 
每一个学生都有对应的归属地。 
学生Student,地址String。 
学生属性:姓名,年龄。 
注意:姓名和年龄相同的视为同一个学生。 
保证学生的唯一性。 
思路:1、描述学生类 
      2、定义一个Map集合,存储学生对象和地址值 
      3、获取Map中的元素 
*/
 
 
class Student implements Comparable<Student>
	{
		private String name;
		private int age;
		Student(String name,int age)
		{
			this.name = name;
			this.age = age;
		}
	    public int compareTo(Student s)
		{
			int num = this.name.compareTo(s.name);
			if(num==0)
				return new Integer(this.age).compareTo(new Integer(s.age));
			return num;
 
		}
		public int hashCode()//重写hashcode
		{
			return name.hashCode()+age*39;
		}
		public boolean equals(Object obj)//重写equals
		{
			if(!(obj instanceof Student))
				throw new ClassCastException("类型不匹配");
			Student s = (Student)obj;
			return this.name.equals(s.name) && this.age == s.age;
		}
 
		public String getName()
		{
			return name;
		}
		public int getAge()
		{
			return age;
		}
		public String toString()
		{
			return name+":"+age;
		}
	}
 
class StuAgeComparator implements Comparator<Student>
{
	public int compare(Student s1,Student s2)
	{
		int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
			if(num==0)
				return s1.getName().compareTo(s2.getName());
			return num;
	}
}
class MapTest 
{
	public static void main(String[] args) 
	{
		//HashMap
		HashMap<Student,String> hm = new HashMap<Student,String>();
 
		hm.put(new Student("lasi1",21),"beijing");
		hm.put(new Student("lasi2",22),"shanghai");
		hm.put(new Student("lasi3",23),"nanjing");
		hm.put(new Student("lasi4",24),"wuhan");
		hm.put(new Student("lasi4",24),"tianjin");
		
		//第一种取出方式 keySet
		Set<Student> keyset = hm.keySet();
		Iterator<Student> it = keyset.iterator();
		while(it.hasNext())
		{
			Student stu = it.next();
			String add = hm.get(stu);
			System.out.println("HashMap第一种取出方式keySet:"+stu.toString()+"--"+add);
		}
			
		System.out.println("------------------------------------");
 
		//第二种取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset = hm.entrySet();
		Iterator<Map.Entry<Student,String>> it1 = entryset.iterator();
		while(it1.hasNext())
		{
			Map.Entry<Student,String> me = it1.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("HashMap第二种取出方式 entrySet:"+stu.toString()+"::"+add);
		}
		System.out.println("------------------------------------");
 
		//TreeMap
		TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuAgeComparator());
 
		tm.put(new Student("blisi1",21),"beijing");
		tm.put(new Student("alisi2",22),"shanghai");
		tm.put(new Student("dlisi3",23),"nanjing");
		tm.put(new Student("clisi4",24),"wuhan");
		tm.put(new Student("clisi4",24),"tianjin");
 
		//第二种取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset1 = tm.entrySet();
		Iterator<Map.Entry<Student,String>> it2 = entryset1.iterator();
		while(it2.hasNext())
		{
			Map.Entry<Student,String> me = it2.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("TreeMap比较器 按年龄排序:"+stu.toString()+"..."+add);
		}
 
		System.out.println("------------------------------------");
 
		TreeMap<Student,String> tm1 = new TreeMap<Student,String>();
 
		tm1.put(new Student("blisi1",21),"beijing");
		tm1.put(new Student("alisi2",22),"shanghai");
		tm1.put(new Student("dlisi3",23),"nanjing");
		tm1.put(new Student("clisi4",24),"wuhan");
		tm1.put(new Student("clisi4",24),"tianjin");
 
		//第二种取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset2 = tm1.entrySet();
		Iterator<Map.Entry<Student,String>> it3 = entryset2.iterator();
		while(it3.hasNext())
		{
			Map.Entry<Student,String> me = it3.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("TreeMap元素自身比较性 按姓名排序:"+stu.toString()+"..."+add);
		}
 	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
例:"fajkgvzvbzjhfaf"获取该字符串中的字母出现的次数,希望打印的结果是:a(1)c(2).....
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
"fajkgvzvbzjhfaf"获取该字符串中的字母出现的次数,
希望打印的结果是:a(1)c(2).....
通过结果发现,每个字母都有对应的次数,说明字母和次数之间有映射关系
何时使用Map集合:当量数据之间存在着映射关系的时候,就应该想到使用Map集合。
 
思路:1、将字符串转换为字符数组 ,因为要对每一个字母进行操作。
      2、定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
      3、遍历字符数组。
			将每一个字母作为键去查Map集合。
			如果返回null,将该字母和1存入到Map集合中。
			如果返回不是null,说明该字母在Map集合已经存在并有对应次数。
			那么就获取该次数并进行自增。然后将该字母和自增后的次数存入到Map集合中,覆盖掉原来键所对应的值。
 
	
	  用数组去遍历集合,如果集合中有该字母则次数加1,如果集合中没有则存入 
      4、将Map集合中的数据变成指定的字符串形式返回。
*/
 
import java.util.*;
class  MapTest1
{
	public static void main(String[] args) 
	{
		charCount("fajkgvzvbzjhfaf");
	}
	
	public static String charCount(String s)
	{
		char[] ch = s.toCharArray();
 
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		
		for (int x=0; x<ch.length; x++)
		{
			Integer value = tm.get(ch[x]);
			if (value==null)
				tm.put(ch[x],1);
			else
			{
				value = value+1;
				tm.put(ch[x],value);
			}
		}
		
 
		Set<Character> keyset = tm.keySet();
 
		Iterator<Character> it = keyset.iterator();
		while(it.hasNext())
		{
			Character c = it.next();
			Integer i = tm.get(c);
			System.out.print(c.toString()+"("+i+")");
		}
		return null;
	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
4、Map扩展
Map扩展知识:Map集合被使用是因为具备映射关系。
例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/*
Map扩展知识:Map集合被使用是因为具备映射关系。
"yureban"   "01"  "zhangsan"
"yureban"   "02"  "lisi"
"jiuyeban"  "01"  "wangwu"
"jiuyeban"  "02"  "zhaoliu"
*/
class Student
{
	private String num;
	private String name;
	Student(String num,String name)
	{
		this.num = num;
		this.name = name;
	}
	public String toString()
	{
		return num+"...."name;
	}
}
class  MapTest2
{
	public static void main(String[] args) 
	{
		HashMap<String,String> yure = new HashMap<String,String>();
 
		yure.put("01","zhangsan");
		yure.put("02","lisi");
		
		HashMap<String,String> jiuye = new HashMap<String,String>();
 
		jiuye.put("01","wangwu");
		jiuye.put("02","zhaoliu");
 
		HashMap<String,HashMap<String,String>> czbk =new  HashMap<String,HashMap<String,String>>();
 
		czbk.put("yureban",yure);
		czbk.put("jiuyeban",jiuye);
 
		Set<String> keyset = czbk.keySet();
 
		Iterator<String> it = keyset.iterator();
		while(it.hasNext())//双重循环
		{
			String s = it.next();
			HashMap<String,String> room = czbk.get(s);
 
			Set<String> keyset1 = room.keySet();
 
			Iterator<String> it1 = keyset1.iterator();
			while(it1.hasNext())//双重循环
			{
				String num = it1.next();
				String name = room.get(num);
				System.out.println(s+":"+num+"--"+name);
			}
		}	
	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
 
二、Collections
 
1、概述
        Collections是对集合框架的一个工具类。它里边的方法都是静态的,不需要创建对象。并未封装特有数据。
        在Collections工具类中大部分方法是用于对List集合进行操作的,如比较,二分查找,随机排序等。
 
2、常见操作
a、排序:        
        void sort(Lsit<T> list);//根据自然顺序对list集合中的元素进行排序
        void sort(List<T> lsit,Comparator<? super T> c);//根据指定比较器c的排序方式对list集合进行排序
b、查找
        Tmax(Collection<? extends T> coll);//根据集合的自然顺序,获取coll集合中的最大元素
        Tmax(Collection<? extends T> coll,Comparator<? super T> comp);//根据指定比较器comp的顺序,获取coll集合中的最大元素
        intbinarySearch(Lsit<? extends Comparable<? super T>> list,Tkey);//二分法查找list集合中的指定对象
c、替换
        voidfill(List<? super T> list, T obj);//将list集合中的全部元素替换成指定对象obj
        booleanreplaceAll(List<T> lsit,T oldVal,T newVal);//用newVal替换集合中的oldVal值
        void swap(Listlist,int i,int j);/在指定列表的指定位置处交换元素
        void shuffle(List<?> list);//使用默认随机源对list集合中的元素进行置换
d、反转
        reverse(List<?> list);//反转list集合中元素的顺序
        Comparator reverseOrder();//返回一个比较器,强行逆转了实现Comparable接口的对象的自然顺序
        ComparatorreverseOrder(Comparator<T> cmp);//返回一个比较器,强行逆转了指定比较器的顺序
e、同步的集合
        List<T>synchronizedList(List<T> list);//返回支持的同步(线程安全的)List集合
        Map<K,V>synchronizedList(Map<K,V> m);//返回支持的同步(线程安全的)Map集合
 
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class  CollectionsDemo
{
	public static void main(String[] args) 
	{
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("aaa");
		list.add("z");
		list.add("kkkkkk");
		list.add("qq");
		list.add("cc");
		
		sop(list);
		//元素自身比较性排序
		Collections.sort(list);
		sop(list);
		
		String max = Collections.max(list);
		sop("max="+max);
 
		int index = Collections.binarySearch(list,"aaa");
		sop("''aaa'':index="+index);
		index = Collections.binarySearch(list,"aaaa");
		sop("''aaaa'':index="+index);
				
		sop("------------------------------------------------");
		//比较器排序
		Collections.sort(list,new StuLenComparator());
		sop(list);
 
		max = Collections.max(list,new StuLenComparator());
		sop("max="+max);
 
		index = Collections.binarySearch(list,"aaa",new StuLenComparator());
		sop("''aaa'':index="+index);
 
		sop("------------------------------------------------");
		
		Collections.reverse(list);
		sop(list);
		Collections.replaceAll(list,"z","fff");
		sop(list);
		Collections.fill(list,"shasha");
		sop(list);
	}
	//二分法原理
	public static int halfSearch(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;
			String str = list.get(mid);
			int num = str.compareTo(key);//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 sop(Object obj)
	{
		System.out.println(obj);
	}
}
 
class StuLenComparator 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);
	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
 
三、Arrays
 
1、概述
     Arrays是用于操作数组的工具类。里边的方法也全是静态的。不需要创建对象。

2、常见操作

数组变集合
Lsit<T> asList(T... a);//将数组转换为集合
把数组变成List集合的好处:可以使用集合的思想和方法来操作数组中的元素。如:contains,get,indexOf,subList等方法。
注意:
        a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
        b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
        c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
 
集合变数组
        Collection接口中的toArray方法。
        <T> T[]toArray(T[] a);将集合变为指定类型的数组。
a、指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
        当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
        所以创建一个刚刚好的数组最优。
b、为什么要将集合变数组?
为了限定对元素的操作。不需要进行增删了。
 
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ArraysDemo 
{
	public static void main(String[] args) 
	{
		//将数组转换为集合
		sop("数组变集合-----------------");
		int[] arr = {2,5,9};
		sop(Arrays.toString(arr));
 
		String[] str = {"abc","cc","kkkkk"};
		List<String> list = Arrays.asList(str);
		sop(list);
		sop("contains:"+list.contains("cc"));
		//list.add("uu");//UnsupportedOperationException
 
		List<int[]> li = Arrays.asList(arr);
		sop(li);
		
		Integer[] num = {2,5,9};
		List lis = Arrays.asList(num);
		sop(lis);
 
		//集合变数组
		sop("集合变数组-----------------");
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
 
		String[] s = al.toArray(new String[al.size()]);
		sop(Arrays.toString(s));
		s = al.toArray(new String[5]);
		sop(Arrays.toString(s));
 
	}
 
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
 
四、增强for循环

1、格式:
        for(数据类型  变量名 :被遍历的集合(collection)或者数组)
        {
            执行语句
        }
2、注意:
        a、对集合进行遍历。只能获取集合元素。但是不能对集合进行操作。可以看作是迭代器的简写形式。
        b、迭代器除了遍历,还可以进行remove集合中元素的动作。如果使用ListIterator,还可以在遍历过程中对集合进行增删改查的操作。
3、传统for和高级for的区别:
高级for有一个局限性。必须有被遍历的目标(集合或数组)。
建议在遍历数组的时候,还是希望使用传统for。因为传统for可以定义脚标。
代码示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ForEachDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
 
		for(String s : al)
			System.out.println(s);
 
		int[] arr = {3,5,8};
		for(int i : arr)
			System.out.println(i);
 
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		
		for(Integer i : hm.keySet())
			System.out.println(i+"---"+hm.get(i));
		
		for(Map.Entry<Integer,String> me : hm.entrySet())
			System.out.println(me.getKey()+"..."+me.getValue());
	}
}</span>
运行结果:
uploading.4e448015.gif转存失败重新上传取消
 
五、可变参数
    如果一个方法在参数列表中传入多个参数,个数不确定,那么每次都要复写该方法。这时可以用数组作为形式参数。但是在传入时,每次都需要定义一个数组对象,作为实际参数。在JDK1.5版本后,就提供了一个新特性:可变参数。
    可变参数其实就是数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。
    在使用时注意:可变参数一定要定义在参数列表的最后面。
 
 
六、静态导入
 
1、格式:
        import  static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
        import  static  java.lang.System.*//导入了Ssytem类中所有静态成员。
       没加static导入的是类,加上static导入的全是某一个类中所有的静态成员。这样写在调用该类的静态方法时可以不用再写类名。如:Arrays.sort(数组);就可以直接写sort(数组);

2、注意:
       当类名重名时,需要指定具体的包名。当方法重名时,需要指定具体所属的对象或者类。
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章