Java学习日记 | Map | HashMap | TreeMap | 散列表 | 泛型

1. Map

        1.1 概述

        Map是无序的,并且保存的是K-V键值对映射关系,其中K不能重复,V可重复
                HashMap:底层是散列表
                TreeMap : 底层是红黑树,元素必须按照一定的规则进行排序
        映射关系: 比如 商品 和 购买数量,或者数据统计
        "akshdkjhwqgheghgbsjkasdjaskhrjqw"统计每个字符出现的个数 使用 HashMap进行存储,字符做K 次数做V

        散列表 : 用于存储键值对映射关系(K-V) , 存储方式为数组中保存链表,用于解决哈希冲突问题

        java中 散列表 对应的就是 HashMap

        但是1.8开始,为了提高查询效率,引入了红黑树

        想要把数据添加在散列表中,需要根据key生成hash值(java中指的hashCode方法),然后根据算法得到数组下标

        如果下标中没有对应的数据,则添加到数组中即可

        如果下标中有对应的数据,则需要调用要添加的key和对应的数据进行比较(equals),如果发生重复,则value值替换

        如果不重复,说明是hash冲突,则把k-v插入的对应的链表中(节点对象中,包含4个属性: hash值,key,value,next)

        相同对象生成多次hash,一定是相同的值,但是不同对象也有可能生成相同的hash值,叫哈希冲突

        1.2 继承体系 

         1.3 常用方法

 2. HashMap

       2.1 使用方法

public static void main(String[] args) {
		Map map = new HashMap();
		// 支持K和V都是null,但没意义
		map.put(null, null);
		map.put("a", 1);
		map.put("A", 2);
		map.put('A', 3);
		map.put('A', 4);
		map.put(65, 5);
		// 删除
		map.remove("a");
		// 修改,key不能修改,只能改value值,和添加操作一样
		// key不存在,则为添加,key存在,则是修改
		map.put("A", 22);
		// 查询,根据key返回value值
		System.out.println(map.get('A'));
		System.out.println(map);
		// 个数
		System.out.println(map.size());
		// 是否为空
		System.out.println(map.isEmpty());
		// 是否包含某个key
		System.out.println(map.containsKey("a"));
		// 是否包含某个value
		 System.out.println(map.containsValue("1"));
		// 清空
		 map.clear();
	}

        2.2 遍历方法

public static void main(String[] args) {
		Map map = new HashMap();
		map.put("a1", 1);
		map.put("a2", 2);
		map.put("a3", 3);
		map.put("a4", 4);
		map.put("a5", 5);
		// 打印输出的格式为key = value
		System.out.println(map);
		
		// 打印value值
		// values() 获取所有的value
		Collection values = map.values();
		for (Object object : values) {
			System.out.print(object + " ");
		}
		System.out.println();
		
		// 打印key值
		// 把key值取出保存在Set中
		Set set = map.keySet();
		for (Object object : set) {
			System.out.print(object + " ");
		}
		System.out.println();
		
		// 按指定格式输出
		// 把map转换成entry对象,保存在set中
		Set set2 = map.entrySet();
		for (Object object : set2) {
			// 默认会以 key = value 的形式输出
			// System.out.println(object);
			Entry entry = (Entry) object;
			System.out.print(entry.getKey() + ":" + entry.getValue() + " ");
		}
		System.out.println();
		
		// 箭头函数遍历map
		map.forEach((x,y) -> {
			System.out.println(x + ":" + y);
		});
	}

        2.3 HashSet 

        当我们使用HashSet的时候,其实就等于是再使用HashMap

        添加数据的时候,虽然调用的是HashSet的add方法,但是本质还是调用map的put方法

        Ps : 在map中,put是添加操作

        而 map中 需要保存的是k和v映射关系,所以在set中有一个变量保存了value的值

        所以我们再进行set添加的时候,只操作了map中的key,value值我们不再关心

3. TreeSet

        3.1 概述

        会按照key排序,所以使用treeMap时,key必须有两个比较器中任意一种

        注意,因为TreeMap会排序,需要比较,所以类型必须一致

        意味着 treeMap中必须保存同类型的数据

         3.2 使用方法

    TreeMap map = new TreeMap();
    map.put("a1", 1);
    map.put("a2", 2);
    map.put("a3", 3);
    map.put("a4", 4);
    map.put("a5", 5);
    // 打印
    System.out.println(map);
    // 获取key值保存在set中
    map.keySet();
    // 将map保存在Entry中
    map.entrySet();
    // 获取value值
    map.values();
    // map中是否包含某个key值
    map.containsKey("");
    // map中是否包含某个value值
    map.containsValue("");
    // map是否为空
    map.isEmpty();
    // 清空
    map.clear();
    // 个数
    map.size();
    // 根据key值获取
    map.get("");
    // 删除
    map.remove("");
    // 添加
    map.put("","");

4. 散列表

        4.1 概述

        散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

        给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

        4.2 底层逻辑

5. 泛型

        5.1 概述

        泛型 : 类型检查

        没有使用泛型之前,集合中可以存储任意类型的数据,均会转型为Object类型

                优点 : 什么都能放

                缺点 : 由于什么都能放,导致获取数据时,得到的是Object,想要使用对象特有属性时,需要强制类型转换(向下转型)

        使用泛型之后,集合中只能保存单一类型的数据

                优点 : 由于保存数据的类型一致,所以使用的时候,不需要向下转型

                缺点 : 只能保存单一数据类型

        泛型:只能写引用类型,不能写基本类型,如果要保存数字,应该写Integer类型(对应 的包装类)

         5.2 使用方法

public static void main(String[] args) {
		List list = new ArrayList();
		// 可以添加任意类型
		list.add(1);
		list.add("a");
		list.add(3.14);
		
		List<String> listStrings = new ArrayList<String>();
		listStrings.add("123");
		listStrings.add("abc");
		// 添加String泛型之后只能添加字符串类型
		// 添加其他类型会报错
//		listStrings.add(123);
	}
public static void main(String[] args) {
		// String类型 默认是根据ASCII码来进行排序的
		// 我们的需求是根据对应的数值大小来排序
		Map<String, Integer> map = new TreeMap<String, Integer>(new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				return Integer.parseInt(o1) - Integer.parseInt(o2);
			}
		});
		map.put("1", 1);
		map.put("20", 2);
		map.put("15", 3);
		map.put("6", 4);
		map.put("10", 5);
		System.out.println(map);
	}

         5.3 注意

        5.4 自定义泛型

        定义泛型,使用大写字母A-Z表示,写什么都一样,都只是占位符而已,只不过 某些字符也有一些特殊的含义

        E: Element 一般代表元素,而集合中的数据 我们叫元素,所以在集合中出现的泛型一股使用E表示
        K : Key 表示键
        V : value 表示值 K和V一般在散列表中出现(Map)
        T:Type 表示一个java类型
        N:表示Number
        ?: 表示不确定的类型
        如果规定了泛型,但是使用的地方没有指定泛型,则默认为Object类型

public static void main(String[] args) {
		Myclass myclass = new Myclass();
		myclass.m("a");
		myclass.m(123);
		
		Myclass<String> myclass2 = new Myclass<String>();
		myclass2.m("abc");
		// 传入数值 报错
//		myclass2.m(123);
	}
}
class Myclass<T>{
	public void m(T obj) {
		System.out.println(obj);
	}

        5.5 Map 以 value值排序

public static void main(String[] args) {
		Map<String, Integer> map = new TreeMap<String, Integer>();
		map.put("a1", 3);
		map.put("a2", 1);
		map.put("a3", 4);
		map.put("a4", 5);
		map.put("a5", 2);
		System.out.println(map);
		// 1. 把map中键值对,封装到entry中,取出并存储在Set中
		Set<Entry<String, Integer>> set = map.entrySet();
		// 2. 把Set转存在List中
		ArrayList<Entry<String, Integer>> list = new ArrayList<Entry<String,Integer>>(set);
		// 对ArrayList进行排序,排序时,按照value排序即可
		list.sort(new Comparator<Entry<String, Integer>>() {

			@Override
			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				return o1.getValue() - o2.getValue();
			}
		});
		System.out.println(list);
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值