JavaSE入门——Map

文章目录

  • Map
    • HashMap
      • HashSet和HashMap
      • 如何向hash表中添加数据
    • TreeMap
    • Map的遍历展示
    • 泛型
      • 自定义泛型

Map

Map是无序可重复的,他是以键值对entry(key,value)的形式存储, 键值对里面的value可重复,key不可重复

操作
put(key,value),添加数据
clear(),清空
size(),查询键值对个数
isEmpty();判断是否为空
get(key) 根据key获得所有的value,以集合形式返回,这里面最终也是values
vaules() 获取所有value,
containsValue(key),判断是否包含key
containsValue(value),判断是否包含value
keySet() 获取所有key ,以set形式返回
entrySet() 获取键值对,以set形式返回
remove (),移除和删除

注意

  • map里面的操作和集合类似,但是两者本质不同
  • map 不能直接遍历,
  • map 由于key 不可以重复,value可以重复 ,当添加数据时,如果有相同的key 值时,只需要将后面添加的这个键值对里面的value覆盖前面的就行。

HashMap

HashMap的底层是散列表,又叫哈希表。

哈希表:又叫散列表,用来保存键值对(key,value)。 根据元素的hash值,通过hash算法就能确定要把元素添加到链表中

哈希算法:一种安全加密算法,把不定长的值,更改为定长的值,就能保证其值的唯一性

哈希算法在java中指的是hashCode()函数

目标:给每一个对象生成唯一的 标识符

hash目的:为了查询快,hash值是一个固定的值,整型值,所以在定长的情况下,查询极快

HashSet和HashMap

HashSet就是HashMap的一个封装,只不过把value值屏蔽了,只保存使用了key。

如何向hash表中添加数据

先调用要存储的映射关系的key对象,调用key对象的hashCode()方法,生成hash码值,然后根据hash值通过hash算法进行hash,得到数组下标,然后向数组中添加元素

  • 如果数组中还没有对应的hash数据,就占用一个数组空间,保存这个key-value的映射关系
  • 如果有数据,那就调用key的equals方法,逐个与hash值相同的链表进行比较,如果返回true,就代表有这个key,此时key不添加,如果返回false,说明只是hash值相同的不同对象,那么就把该对象掺入到链表中
    HashSet只保存一个元素 HashMap保存键值对

注意:添加的元素要实现equals方法和hashCode方法,equals用于比较是否添加,hashCode 用于计算是hash值

TreeMap

和TreeSet差不多(SortedSet的唯一实现类),TreeMap也是SortedMap的实现类,
TreeMap是可以使用比较器类来排序的(也就是说八种基本数据类型 的包装类是默认排序的)。

但是TreeMap只能根据键值对中的key 来排序,不能根据value来排序, 想要根据value来排序需要转换为list,同理hashMap 也可以转换为list来排序,但他们本身在这种情况下是不能排序的。(怎么转换,下一篇会写到)

TreeMap 排序

public class Collection_16_SortedMap_02 {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void main(String[] args) {
		SortedMap products = new TreeMap();
		Product2 p1 = new Product2("water", 1.3);
		Product2 p2 = new Product2("apple", 4.5);
		Product2 p3 = new Product2("banner", 3.5);
		Product2 p4 = new Product2("coffer", 8.0);

		// value 可以设置为已购买的数量
		products.put(p1, 1.0);
		products.put(p2, 2.0);
		products.put(p3, 3.0);
		products.put(p4, 4.0);

		Set keys = products.keySet();
		for (Object key : keys) {
			Product2 p = (Product2) key;
			double value = (double) products.get(key);
			System.out.println(p + "--->" + value + "kg 总价 = " + (value * p.price));
		}
	}

}

@SuppressWarnings("rawtypes")
class Product2 implements Comparable {
	String name;
	double price;

	public Product2(String name, double price) {
		super();
		this.name = name;
		this.price = price;
	}

	@Override
	public String toString() {
		return "Product2 [name=" + name + ", price=" + price + "]";
	}

	@Override
	public int compareTo(Object arg0) {
		double price1 = this.price;
		double price2 = ((Product2) arg0).price;
		if (price1 == price2) {
			return 0;
		} else if (price1 < price2) {
			return -1;
		} else {
			return 1;
		}
	}

}

Map的遍历展示

前文也提到Map不能直接遍历。

当然你想查看结果,可以直接打印map对象的名字,他会在控制台以数组的形式,以=连接键值对的key和value.

但是如果想用foreach直接打印却不行,

//		获取所有的value
		Collection values =map.values();
		for (Object object : values) {
			System.out.println(object);
		}
		
		
		System.out.println("-------------------");

		//或者把map中的key取出,形成set
		Set s =map.keySet();
		for (Object object : s) {
			//通过对应的ke'y遍历相应的value
			System.out.println(object+":"+map.get(object));
		}
		System.out.println("-------------------");

		
		//或者把map中的所有entry取出,形成set         entry覆写了toString方法,会以key=value的形式展示
		Set set =map.entrySet();
		for (Object object : set) {
			System.out.println(object);
		}
		

泛型

泛型就是给一个存储指定一个存储类型,只有指定的能存储,其他不能,如集合,集合实际上和数组一样,只能存储统一数据类型,只不过是Object类型,所有元素都会发生向上转型,所以导致什么都能放。
注意:
泛型不能使用基本数据类型,只能使用引用数据类型

优点:统一类型,减少类型转换
缺点:只能存储单一类型的元素

	public static void main(String[] args) {
		A a =new A();
		B b =new B();
		C c =new C();
		
//		没用泛型,繁琐
//		Set s=new HashSet();
//		s.add(a);
//		s.add(b);
//		s.add(c);
//		for (Object object : s) {
//			if (object instanceof A ) {
//				A d = (A) object;
//				d.m1();
//			}else if (object instanceof B) {
//				B d = (B) object;
//				d.m1();
//			}else if(object instanceof C) {
//				C d=(C) object;
//				d.m1();
//			}
//		}
		
		List<D> ds =new ArrayList<D>();
		ds.add(a);
		ds.add(b);
		ds.add(c);
		for (D d : ds) {
			d.m1();
		}
	
	}

}
interface D{
	public void m1();
}
class A implements D{

	@Override
	public void m1() {
		System.out.println("A的m1方法");
	}
	
}
class B implements D{
	
	@Override
	public void m1() {
		System.out.println("B的m1方法");
	}
	
}
class C implements D{
	
	@Override
	public void m1() {
		System.out.println("C的m1方法");
	}
	

自定义泛型

如果人家规定了泛型,我们没有传递 类型使用的情况下,泛型类型就是object,

常用的如下:
T(type) 表示具体的一个Java类型
K V (key,value)分别代表Java键值中的key value
E (element)代表Element

自定义

		List<User> users = new ArrayList<User>();
		users.add(new User(12));
		users.add(new User(11));
		users.add(new User(15));
		for (User user : users) {
			System.out.println(user.age);
		}
		
		
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("sad", 2);
	}

}
class User {
	int age;

	public User(int age) {
		super();
		this.age = age;
	}
	
}

你可能感兴趣的:(学习笔记,JavaSE,java)