Map集合不继承Collection,Map是映射键值对,存储对象的时候,一次性存储两个对象,一个作为键(K),一个作为值(V)。

区别:

Collection一个对象存储方式是add

Map 两个对象存储方式 put()

Map集合中,不能出现重复键,每一个键最多只能映射一个值,但是不同键可以有相同值

一、Map中的方法

直接上demo

package map;
/*
 * Map中的方法
 */
import java.util.*;
public class MapDemo {
	public static void main(String[] args) {
		/*method1();
		method2();
		method3();
		method4();*/
		method5();
	}
	/*
	 * put(k,v)将键值存储到集合中
	 */
	public static void method(){
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 1);
		map.put("b", 1);
		map.put("c", 1);
		map.put("d", 4);
		map.put("e", 6);
		System.out.println(map);
	}
	
	/*
	 * putAll(Map map)把一个集合全部插入另一个集合
	 * 
	 */
	public static void method1(){
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 1);
		map.put("b", 1);
		map.put("c", 1);
		
		Map<String,Integer> map2 = new HashMap<>();
		map2.put("e", 2);
		map2.put("f", 3);
		map2.put("g", 4);
		
		map.putAll(map2);

		System.out.println(map);
	}
	
	/*
	 * V get(Key) 传递一个键,返回键对应的值,如果此键不存在,返回为空
	 */
	public static void method2(){
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 234);
		map.put("b", 1);
		map.put("c", 1);
		System.out.println(map.get("z"));
	}
 
	/*
	 * void clear() 清除所有对象
	 * void isEmpty() 判断是为空
	 * int size() 返回映射关系对的个数
	 * boolean containsKey(Key) 判断键是否存在,存在返回真,否则返回假
	 * boolean containsValue(Value) 同理判断值是否存在,存在返回真,不存在返回假
	 */
	public static void method3(){
			Map<String,Integer> map = new HashMap<>();
			map.put("a", 1);
			map.put("b", 123);
			map.put("c", 124);
			System.out.println(map.size());
			System.out.println(map.containsKey("A"));
			//自动装箱,会调用equals判断,所以为真
			System.out.println(map.containsValue(new Integer(124)));
			map.clear();
			System.out.println(map.isEmpty());
	}
  
	/*
	 * V remove(K)
	 * 移除指定的键值对,传递键,返回值
	 * 没有移除成功返回null
	 */
	public static void method4(){
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 1);
		map.put("b", 123);
		map.put("c", 124);
		System.out.println(map.remove("a"));
		System.out.println(map);
	}
  
	/*
	 * Collection<V> values()将Map中的所有值,存储到Collection集合
	 */
	public static void method5(){
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 1);
		map.put("b", 123);
		map.put("c", 124);
		
		Collection<Integer> c = new ArrayList<>();
		
		c = map.values();
		System.out.println(map);
		System.out.println(c);
	}
	
}

二、Map集合的取出方法

遍历Map集合有两种方法,一种是利用set集合遍历,另外一种是利用内部类原理进行遍历。

Demo

package map;

import java.util.*;

public class MapDemo1 {
	/*
	 * 练习map的两种数据取出方式
	 */
	public static void main(String[] args) {
		method1();
	}
	
	/*
	 * 利用set取出
	 */
	public static void method(){
		Map<String, Integer> map = new HashMap<>();
		
		map.put("a",1);
		map.put("b",2);
		map.put("c",3);
		map.put("d",4);

		Set<String> set = map.keySet();
		
		Iterator<String> it = set.iterator();
		while(it.hasNext()){
			System.out.println(map.get(it.next()));
		}
	}
	
	/*
	 * 利用集合的键值对关系对象获取 entrySet,这是一个内部类
	 */
	public static void method1(){
		Map<String, Integer> map = new HashMap<>();
		
		map.put("a",1);
		map.put("b",2);
		map.put("c",3);
		map.put("d",4);
		
		Set<Map.Entry<String, Integer>> o = new HashSet<>();
		
		o = map.entrySet();
		
		Iterator<Map.Entry<String, Integer>> it = o.iterator();
		
		while(it.hasNext()){
			//利用多态,next返回实现类对象给接口,可以不用管具体的实现类原理
			Map.Entry<String, Integer> entry = it.next();
			
			System.out.println(entry.getKey());
			System.out.println(entry.getValue());
		}		
	}
}

三、增强for循环间接遍历map

实现的原理其实和上面的set遍历相似,因为map小的小弟们没有实现接口Iterable,所有不能使用增强for循环,因此map也就没有办法使用增强for循环来遍历了。所以,借助Key的set集合来使用for循环,从而间接遍历可以获取到map集合中的数据,同样,这种方式也可以和map的取出方法一样,有两种写法。

demo

package map;
/*
 * for循环遍历间接遍历map
 */
import java.util.*;

public class MapDemo2 {
	public static void main(String[] args) {
		
		Map<String, Integer> m = new HashMap<>();
		m.put("a", 1); 
		m.put("b", 2); 
		m.put("c", 3);
		
      //1.利用普通的set方法for循环遍历,平时中推荐使用
		/*for(String s : m.keySet()){
			System.out.println(s+"----" +  m.get(s));
		}*/
	//2.同样,使用内部类来进行实现	
		for(Map.Entry<String, Integer> entry : m.entrySet()){
			System.out.println(entry.getKey() + "..."+  entry.getValue());
		}
	}
}

四、HashMap类

基于哈希表的映射键值对,线程不安全,可以存储null值和null键,没有顺序。要求键是唯一的,对象必须重写hashCode方法和equals方法。

demo

package map;
/*
 * HashMap集合的存取自定义对象
 * Person是之前自定义的对象
 */

import SetDemo.Person;
import java.util.*;

public class HashMapDemo {
	public static void main(String[] args) {
		HashMap<Person,String> hm = new HashMap<>();
		
		hm.put(new Person("张三",22), "加拿大");
		hm.put(new Person("李四",42), "澳大利亚");
		hm.put(new Person("王五",71), "美国");
		hm.put(new Person("赵六",54), "英国");
		
		method1(hm);
	}
	
	/*
	 * 实现map集合的第一种获取方法
	 */
	public static void method(HashMap<Person,String> hm){
		
		Set<Person> set  = hm.keySet();
		
		Iterator<Person> it = set.iterator();
		
		while(it.hasNext()){
			Person p = it.next();
			
			String s = hm.get(p);
			
			System.out.println(p + ".." + s);
		}
	}
	
	/* 
	 * 第二种方法获取,entry
	 */
	public static void method1(HashMap<Person,String> hm){
		
		Set<Map.Entry<Person, String>> set = hm.entrySet();
		
		Iterator<Map.Entry<Person, String>> it = set.iterator();
		
		while(it.hasNext()){
			Map.Entry<Person, String> e = it.next();
			
			System.out.println(e.getKey() + ".." + e.getValue());
		}		
	}	
}

五、LinkedMap类

LinkedMap是HashMap的子类,基于链表的哈希表实现,有序的Map集合,线程不安全的,开始版本于JDK1.4。

package map;
import java.util.*;
/*
 * LinkedHashMap的存储和遍历
 * 按put的顺序排序
 */

public class LinkedHashMapDemo {
	public static void main(String[] args) {
		LinkedHashMap<String, String> lhm = new LinkedHashMap<>();
		
		lhm.put("a","65" );
		lhm.put("c","67" );
		lhm.put("b","668" );
		lhm.put("A","786" );
		lhm.put("d","786786" );
		
		for(String key : lhm.keySet()){
			System.out.println(lhm.get(key));
		}
	}
}

六、HashTable

底层数据结构也是哈希表,但是不允许存储null,线程安全,运行速度慢。开始版本JDK1.0,没有集合框架以前,存储键值对,只能依靠Hashtable,被HashMap取代,郁郁而终了。但是他有一个子类Properties,依然活跃在开发舞台,这个集合可以和IO流配合使用。

七、TreeMap集合

对存储的键进行排序,需要对象的自然顺序,或者比较器,用法和实现代码,直接参考HashSet集合,线程不安全集合,运行速度快,底层实现红黑树,自然平衡算法二叉树。

package cn.itcast.map;
/*
 * TreeMap存储自定义对象
 * 提供两个排序方式,自然顺序,一个是比较器
 */
import java.util.*;
import SetDemo.PersonComparator;

public class TreeMapDemo {
	public static void main(String[] args) {
      //传递一个自然比较对象进去
		TreeMap<Person,String> tm = new TreeMap<Person, String>(new PersonComparator());
		 tm.put(new Person("lisi",18), "加拿大");
		 tm.put(new Person("zhangsa",17), "澳大利亚");
		 tm.put(new Person("zhangsa",17), "澳大利亚");
		 tm.put(new Person("wangwu",20), "新加坡");
		 tm.put(new Person("zhaoliu",19), "新西兰");
		 tm.put(new Person("zhaoliu",19), "新西兰");
		 tm.put(new Person("lisa",22), "迪拜");
//		 keySet(tm);
		 entrySet(tm);
	}
	/*
	 * 增强for循环,遍历entrySet方式
	 */
	public static void entrySet(TreeMap<Person,String> hm){
		for(Map.Entry<Person, String> entry : hm.entrySet()){
			Person p = entry.getKey();
			String value = entry.getValue();
			System.out.println(p+"..."+value);
		}
	}
	
	/*
	 * 增强for循环,遍历keySet方式
	 */
	public static void keySet(TreeMap<Person,String> tm){
		for(Person p : tm.keySet()){
			String value = tm.get(p);
			System.out.println(p+"..."+value);
		}
	}
}

八、map集合的小练习

题目:统计一个字符串内每个字母出现的顺序,存储在集合之中

package map;

/*
 * 练习:
 * 统计字符串里面每个字符出现的次数,存储到map里面
 * eg:a=1,b=3....
 * 
 */
import java.util.*;
public class HashMapTest {
	public static void main(String[] args) {
		String s = "xcvgbjhmklfdxhkuxck.jbjgcj,ckyfxckh";

		System.out.println(method(s));
	}
	 
	public static Map<Character,Integer> method(String s){
		char[] c = s.toCharArray();
		
		Map<Character,Integer> tongji = new HashMap<Character, Integer>();
		
		for(int i = 0 ; i < c.length ; i++){
			char temp = c[i];
			if(tongji.containsKey(temp)){
				
				tongji.put(temp,tongji.get(temp)+1);
			}
			else{
				tongji.put(temp, 1);
			}
		}
		return tongji;
	}
}

九、Properties类

Hashtable的子类,也是一个线程安全的键值对的集合。这个类不同于其他集合,可以和IO流结合使用,实现数据的永久性存储。查看API发现这个集合没定义泛型,泛型已经被设定好了,键值对的数据类型都是字符串,完全适用于Map中的一切操作。

特有方法setProperty(String key,String value)等同于就是Map中的put,getProperty(String value)传递键,返回对应的值,等同于Map中的get方法, 以后可以用于配置文件。

demo

package map;

/*
 * Properties类的练习
 */

import java.util.*;

public class PropertiesDemo {
	public static void main(String[] args) {
		method1();
		
		Properties pro = System.getProperties();
		
		System.out.println(pro);
		
		System.out.println(pro.get("os.name"));
		
	}
	
	/*
	 * 使用Properties自己的方法操作
	 */
	public static void method1(){
		Properties pro = new Properties();
		pro.setProperty("a", "1");
		pro.setProperty("b", "2");
		pro.setProperty("c", "3");
		pro.setProperty("d", "4");
		pro.setProperty("e", "5");
		
		System.out.println(pro.getProperty("a"));
		System.out.println(pro.getProperty("bb"));

	}
	
	/*
	 * 像map一样操作Properties
	 */
	public static void method(){
		Properties pro = new Properties();
		pro.put(1, 321);
		pro.put(2, 345321);
		pro.put(3, 321);
		pro.put(5, 321);
		pro.put(4, 324534531);
	
		
		System.out.println(pro.get(3));
		
		Set set = pro.keySet();
		
		Iterator it = set.iterator();
		
		while(it.hasNext()){
			Object key = it.next();
			Object value = pro.get(key);
			
			System.out.println(key + "..." + value);
		}
	}
}

十、Collections工具类

Collections中的方法都是静态的,用于操作集合类的。

  • static void sort(List list)根据存储在集合的对象的自然顺序,对List集合排序
  • static void sort(List list,Comparator com)根据比较器对List集合排序
  • static Comparator reverseOrder()返回比较器,逆转对象的自然顺序
  • static Comparator reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
  • static int binarySearch(List list, Objectkey)集合的折半查找,传递List集合必须有序,找到返回下标,找不到返回,返回插入点-1
  • static void fill(List list,Object obj)填充集合
  • static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置
  • static void shuffle(List list)对List集合中的对象,随机换位置
  • 将线程不安全集合变成线程安全集合 synchronized开头的方法
package Collections;

/*
 * 集合工具类的操作方法
 */
import java.util.*;

import SetDemo.Person;
import SetDemo.PersonComparator;

public class CollectionsDemo {
	public static void main(String[] args) {

		method_4();

	}

	/*
	 * static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置 static void
	 * shuffle(List list)对List集合中的对象,随机换位置
	 */
	public static void method_4() {
		List<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		list.add(5);
		list.add(6);
		list.add(7);
		list.add(8);

		System.out.println(list);
		Collections.swap(list, 0, 1);
		System.out.println(list);

		Collections.shuffle(list);
		System.out.println(list);
	}

	/*
	 * static void fill(List list,Object obj)填充集合
	 */
	public static void method_3() {
		List<Integer> list = new ArrayList<>();
		list.add(12);
		list.add(13);
		list.add(15);
		list.add(78);
		list.add(54);

		Collections.fill(list, 2);
		System.out.println(list);
	}

	/*
	 * static int binarySort(List list)集合的折半查找折半查找,
	 */
	public static void method_2() {
		List<Integer> list = new ArrayList<>();
		list.add(12);
		list.add(13);
		list.add(15);
		list.add(78);
		list.add(54);
		list.add(84);
		list.add(25);
		list.add(65);

		int i = Collections.binarySearch(list, 84);

		System.out.println(i);
	}

	/*
	 * static Comparator reverseOrder()返回比较器,逆转对象的自然顺序 static Comparator
	 * reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
	 *
	 */
	public static void method_1() {
		List<Person> list = new ArrayList<>();

		list.add(new Person("liu", 23));
		list.add(new Person("niu", 21));
		list.add(new Person("fei", 222));
		list.add(new Person("zi", 2323));

		Collections.sort(list, Collections.reverseOrder(new PersonComparator()));

		System.out.println(list);
	}

	/*
	 * static void sort(List list) 可以给集合排序 static void sort(List list,Comparator
	 * com)根据比较器对List集合排序
	 */
	public static void method() {
		List<String> list = new ArrayList<>();

		list.add("slkeghk");
		list.add("aftytyj");
		list.add("bturehk");
		list.add("crgresr");

		System.out.println(list);
		Collections.sort(list);
		System.out.println(list);

		List<Person> l = new ArrayList<>();

		l.add(new Person("liu", 23));
		l.add(new Person("niu", 21));
		l.add(new Person("fei", 222));
		l.add(new Person("zi", 2323));

		System.out.println(l);
		Collections.sort(l);
		System.out.println(l);
	}
}

十一、集合数组的互转

数组转成集合  Arrays类方法isList , 传递数组,返回集合。

数组转成集合后,改变集合长度的操作不能做,如果做了,出现不支持的操作异常

集合转数组Collection中方法toArray() 将集合转成数组,传递数组,返回数组

写法:list.toArray(new Object[list.size()]);