HashMap和HashSet的总结(JAVA数据结构)

集合

Java 集合框架Java Collection Framework ,又被称为容器container ,是定义在 java.util 包下的一组接口interfaces 和其实现类classes

Set和Map集合的关系

Set

  • 纯key模型
    应用: 查询某个英文单词在不在字典中

Map

  • key-value模型
    应用:统计每个单词出现的次数<单词,出现次数>

Map集合

Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
Map中存放键值对的Key是唯一的,value是可以重复的.HashMap集合中key和value都可以为null,但是key为null,只能有一个.
Map中的Key可以全部分离出来,存储到Set中来进行访问。
Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入

TreeMap

TreeMap集合中key不能为null,value可以为null

HashMap

map中如何比较两个对象

 必须覆写hashcode()equals方法.

equal相同的两个对象,hashcode是否相同?

一定相同,equal相同,就是同一对象, 试想,如果hashcode()不相同,那肯定不是同一对象,怎么可能equals()相同

hashcode()相同的两个对象,equals是否相同?

不一定相同,只能说明发生了哈希冲突.

public class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof Person) {
            Person person = (Person) obj;
            return this.age == person.age && this.name.equals(person.name);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return 0;
    }

    public static void main(String[] args) {
        Person per1 = new Person("张三", 20);
        Person per2 = new Person("李四", 30);
        Person per3 = new Person("张三", 20);
        Map<Person, Object> map = new HashMap<>();
        map.put(per1, 1);
        map.put(per2, 2);
        map.put(per3, 3);
        //只要equals()方法比较相同,JDK就会认为他们是相同的对象
        System.out.println(map);
        //打印结果:{Person{name='张三', age=20}=3, Person{name='李四', age=30}=2}

        //如果不重写equals(),那么即使他们的hashcode相同,JDK也认为他们是不同的对象
        // 不重写equals() 打印结果为
        //{Person{name='张三', age=20}=1, Person{name='李四', age=30}=2, Person{name='张三', age=20}=3}
    }
}

TreeMap如何保证key的顺序

/**
* TreeMap 和 HashMap 的比较
* TreeMap中元素的保存顺序是由compareTo()方法决定的
* 如果要使用TreeMap集合保存元素,要么实现Comparable,要么传入一个比较器,
* 要不然会报错误   //jcl.Student cannot be cast to java.lang.Comparable
*/
 public static void main(String[] args) {
       
     Set<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return s1.getName().compareTo(s2.getName());
            }
        });

        Student s1 = new Student("diaochan");
        Student s2 = new Student("wangzhoajun");
        Student s3 = new Student("yangyuhuan");
        Student s4 = new Student("xishi");
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        for (Student s : set) {
            System.out.println(s.getName() + "");
        }
    }
}

/**
打印结果:
diaochan
wangzhoajun
xishi
yangyuhuan
	**/

Map的常用方法

  1. put(key, value):插入一个键值对,如果 key 已经存在,则会替换原有的 value 值。

  2. get(key):返回指定 key 对应的 value 值,如果 key 不存在,则返回 null。

  3. containsKey(key):判断 Map 中是否包含指定的 key,如果包含则返回 true,否则返回 false。

  4. containsValue(value):判断 Map 中是否包含指定的 value,如果包含则返回 true,否则返回 false。

  5. keySet():返回 Map 中所有键的集合,即一个 Set 集合。

  6. values():返回 Map 中所有值的集合,即一个 Collection 集合。

  7. entrySet():返回 Map 中所有键值对的集合,即一个 Set 集合,其中每个元素都是一个 Entry 对象,包含一个键和对应的值。

  8. remove(key):移除 Map 中指定 key 对应的键值对,如果 key 不存在,则不进行任何操作。

  9. size():返回 Map 中键值对的数量。

  10. isEmpty():判断 Map 是否为空,如果为空则返回 true,否则返回 false。

Map接口常见子类添加问题

        Map<String, String> map = new HashMap<>();
        //V put(K key, V value)
        //将指定的值与该映射中的指定键相关联
        //key值不重复,value值可以重复
        map.put("豹子头", "林冲");
        map.put("智多星", "吴用");
        map.put("及时雨", "宋江");
        map.put("黑旋风", "李逵");
        //在Map中元素添加的顺序和保存的顺序没有必然联系
        System.out.println(map);
        
        //Set<Map.Entry<K,V>> entrySet()
        //返回此地址中包含的映射的Set视图。
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
        
        //V get(Object key)
        //返回指定键所映射的值,如果不存在,返回null
        System.out.println(map.get("智多星"));
        System.out.println(map.get("智多"));//null
        
        //V put(K key, V value)
        //将指定的值与该映射中的指定键相关联,若key不存在,则新增加一个Entry对象
        //若key存在,则将原来的value改为新的value,并返回原来的value.
        map.put("花和尚", "鲁智深");
        System.out.println(map);
        System.out.println(map.put("花和尚", "小明"));
        System.out.println(map);
        
        //Set<K> keySet()
        //返回此地图中包含的键的Set集合
        System.out.println("当前的所有key为:");
        System.out.println(map.keySet());
        
        //Collection<V> values()
        //返回此地图中包含的值的Collection集合
        System.out.println("当前的所有value为:");
        System.out.println(map.values());

map集合的遍历

  Map<String, String> map = new HashMap<>();
     map.put("豹子头", "林冲");
     map.put("智多星", "吴用");
     map.put("及时雨", "宋江");
     map.put("黑旋风", "李逵");
     //Set<Map.Entry<K,V>> entrySet()
     //返回此地址中包含的映射的Set视图。
     for (Map.Entry<String, String> entry : map.entrySet()) {
         System.out.println(entry.getKey() + "=" + entry.getValue());
     }

     // Set<K> keySet()  返回此地图中包含的键的Set集合
     System.out.println("当前的所有key为:");
     Set<String> strings = map.keySet();
     for (String ret : strings) {
         System.out.println(ret);
     }

     //Collection<V> values()   返回此地图中包含的值的Collection集合
     System.out.println("当前的所有value为:");
     Collection<String> values = map.values();
     for (String ret : values) {
         System.out.println(ret);
     }
/**
打印结果:
map集合的key-value
智多星=吴用
黑旋风=李逵
豹子头=林冲
及时雨=宋江
当前的所有key为:
智多星
黑旋风
豹子头
及时雨
当前的所有value为:
吴用
李逵
林冲
宋江
**/

Set集合

Set是继承自Collection的一个接口类
Set中只存储了key,并且要求key一定要唯一
Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
Set最大的功能就是对集合中的元素进行去重
实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
Set中不能插入null的key。

HashSet

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值