Collection 接口的子类型: Set 接口 Map接口


Collection 接口的子类型: Set 接口:无序(存进和取出的顺序不同),不可重复,元素没有下标

实现Set接口:HashSet类;SortedSet接口是Set接口的子接口,SortedSet接口的实现类:TreeSet类实现了Set接口;

1. HashSet类

底层采取了哈希表这种数据结构,实际上HashSet集合在new的时候,底层是new了一个HashMap集合,向HashSet集合存储元素,实际上是存储到HashMap集合的key部分了

import java.util.HashSet;
import java.util.Set;

public class Hset {
	public static void main(String[] args) {
		//创建HashSet集合
		Set set  =new HashSet<>();
		//添加元素
		set.add("h4");
		set.add("h2");
		set.add("h5");
		set.add("h1");
		set.add("h3");
		set.add("h2");
		set.add("h3");
		//遍历
		for(String i :set) {
			System.out.println(i);
		}
		
	}
//结果:
//	h1
//	h2
//	h3
//	h4
//	h5
}
/*1. 存储顺序和取出顺序不同,不可重复
 *2. 看一下源码:
 * public HashSet() {
        map = new HashMap<>();
    }
    
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    
   就是:向HashSet集合存储元素,实际上是存储到HashMap集合的key部分了
 * */

2.TreeSet类(元素可以自动排序,序指大小)

SortedSet接口:由于继承了Set接口,其特点有无序不可重复,没有下标,但放在SortedSet集合中的元素可以自动排序,我们成为可排序集合
SortedSet接口的实现类的TreeSet类:底层采取了二叉树这种数据结构,实际上TreeSet集合在new的时候,底层是new了一个TreeMap集合,向TreeSet集合存储元素,实际上是存储到TreeMap集合中了

import java.util.Set;
import java.util.TreeSet;

public class Tset {

	public static void main(String[] args) {
		//创建TreeSet集合
		Set set  =new TreeSet<>();
		//添加元素
				set.add("a");
				set.add("b");
				set.add("g");
				set.add("r");
				set.add("d");
				set.add("d");
				set.add("d");
				//遍历
				for(String i :set) {
					System.out.println(i);
				}
	}
//结果:
//a
//b
//d
//g
//r
}
/*
 * 1.从小到大排序*/
 */

Map接口 (以key和value的这种键值对存储元素)

  1. Map接口和Collection 接口没有关系,Map集合以key和value的这种键值对的方式存储元素,key和value都是存储java对象的内存地址,所有Map集合的key都是无序不可重复的,就是说Map集合的key和Set集合存储元素的特点相同,Map集合的key,就是一个Set集合,往Set集合中放数据,实际上放到Map集合的key部分
  2. **Map接口支持泛型: Map **

1.Map接口中常用的方法

**
V put(K key, V value) 向 Map中添加键值对
V get( Object key ) 通过key获取value
void clear() 清空Map集合
boolean containsKey( Object key ) 判断Map中是否包含某个key
boolean containsValue( Object value ) 判断Map中是否包含某个 value
V remove( Object key ) 通过key删除键值对
int size() 获取键值对的数量
Collection values() 获取Map集合中的所有的value ,返回一个Collection集合
boolean isEmpty( ) 判断Map集合中元素的个数是否为0**

package 集合练习;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Map1 {

	public static void main(String[] args) {
	 //创建Map集合对象,对于Map 可以通过泛型分别来统一Map集合中 key 和 value 的类型
		Map map = new HashMap<>();
		
	//1. 向Map集合中添加键值对  V put(K  key, V  value)  
		map.put(1, "diyi");//1是自动装箱
		map.put(2, "dier");
		map.put(3, "disan");
		map.put(4, "disi"); 
		
	//2. 通过key获取value  V get(Object key) 
		String string =map.get(2);
		System.out.println(string);
		
	//3. 获取键值对的数量    int size()  
		System.out.println("键值对的数量:"+map.size());
		
	//4. 通过key删除键值对   V remove(Object  key) 
		map.remove(4);
		System.out.println("此时键值对的数量:"+map.size());
		
	//5.判断Map中是否包含某个key     boolean containsKey( Object key)
		System.out.println(map.containsKey(4));
		
		
	//6.判断Map中是否包含某个value   boolean  containsValue( Object  value ) 
		System.out.println(map.containsValue("diyi"));
		//强调:contains方法底层调用的都是equals方法,所以自定义的类要重写equals方法。
		System.out.println(map.containsValue(new String("diyi")));
		
		
	//7.获取Map集合中的所有的value ,返回一个Collection   Collection values();
		Collection values = map.values();
		for(String s:values) {
			System.out.println(s);
		}
		
		
	//8.  清空Map集合 void clear() 
		map.clear();
		System.out.println(map.size());
		
	}
/*
 * 结果:
dier
键值对的数量:4
此时键值对的数量:3
false
true
true
diyi
dier
disan
0
*/
}

2.Map集合遍历常用的方法

1.第一种,获取所有的key ,存放在Set集合中,通过遍历key, 来遍历value

package 集合练习;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Map2 {

	public static void main(String[] args) {
	 //创建Map集合对象
		Map map = new HashMap<>();
	//向Map集合中添加键值对
		map.put(1, "diyi");//1是自动装箱
		map.put(2, "dier");
		map.put(3, "disan");
		map.put(4, "disi"); 
	//遍历Map集合
		//1.先获取所有的key,所有的key是一个set集合 此处调用keySet方法,返回Set集合 Set keySet() 其中K代表key的类型
		Set keys = map.keySet();
		//2.遍历key ,通过key获取value,其中遍历Set集合方法可以是迭代器,foreach
		//(1)迭代器
		Iterator it = keys.iterator();
		while(it.hasNext()) {
			Integer key = it.next();
			String value = map.get(key);
			System.out.println(key+"="+value);
		}
		//(2)foreach方法
		for(Integer key:keys) {
			System.out.println(key+"="+map.get(key));
		}
		
/*
1=diyi
2=dier
3=disan
4=disi
1=diyi
2=dier
3=disan
4=disi
*/	
	}
}

第二种:把Map集合直接全部转换为Set集合 Set> entrySet() ,Set集合 中的元素类型是Map.Entry ,和String类型一样,只不过Map.Entry是静态内部类,Map下的静态内部类

/* Set> entrySet()  返回Set集合,其中每个对象都是Map.Entry类型
	 * 每个对象Node包含两个属性:Integer key属性, String value属性
		就是将每个Map键值对,转换为Set集合中的一个一个对象Node*/
		Set> set = map.entrySet();
		
	//遍历Set集合,每一次取出一个Node
		//(1)迭代器
		Iterator> iterator2 = set.iterator();
		while(iterator2.hasNext()) {
			Map.Entry node = iterator2.next();
			Integer key =node.getKey();
			String value  = node.getValue();
			System.out.println(key+"="+value);
		}
		/*源码:
		 * interface Entry {
		 *    K getKey();
		 *    V getValue();

static class Node implements Map.Entry {
        final int hash;
        final K key;
        V value;
        Node next;
		 * }*/
		
		//(2)foreach方法
		for(Map.Entry node:set) {
			System.out.println(node.getKey() + "=" + node.getValue());
	}
		/*
		1=diyi
		2=dier
		3=disan
		4=disi
		1=diyi
		2=dier
		3=disan
		4=disi
		*/	

}

分析以上两种,第二种效率更高,因为获取key和value都直接从node对象中获取的属性值,当数据量较大,可以优先选择

静态内部类(了解一下)

public class ZongClass {

	public static void main(String[] args) {

		//类名调用内部类静态方法,注意:类名指ZongClass.InnerClass
		ZongClass.InnerClass.m1();
		
		//创建内部类对象调用静态内部类的实例方法
		ZongClass.InnerClass mClass = new ZongClass.InnerClass();
		mClass.m2();
	}
	//声明一个静态内部类
	static class InnerClass{
		
		public static void m1() {
			System.out.println("静态内部类的静态方法m1执行");
		}
		
		public void m2() {
			System.out.println("静态内部类的实例方法m2执行");
		}
		
	}
}

相关