Java HashMap 哈希映射


HashMap

  • HashMap 又称哈希映射或散列映射,其实现 Map 并扩展了 AbstractMap,本身没有增加任何新的方法;
  • HashMap 是无序的,元素加入散列映射的顺序并不是它们被迭代器读出的顺序;
  • HashMap 通过哈希表计算 键-值 的存储位置,最多允许一个 null,不支持线程同步;
  • HashMap 在面对大型的集合时,可以使 get() 和 put() 的运行时间保持恒定;

1. 构造方法

构造方法说明
HashMap()构造一个默认的散列映射
HashMap(Map m)用 m 的元素初始化散列映射
HashMap(int capacity)将散列映射的容量初始化为 capacity
HashMap(int capacity, float fillRatio)用参数初始化散列映射的容量和填充比

2. 常用方法

  • HashMap 的 key 是唯一的,重复 put() 会覆盖前面的;
  • 遍历可以使用键找值或键值对的方法,都是先转变为集合,在处理大数据时推荐使用 entrySet(),这样可以更快,但是比较耗内存,详见:Java 测试 HashMap 的两种遍历方法
  • 键找值遍历:Set<K> set = map.keySet();for(key : set){Value = map.get(key);}
  • 键值对遍历:Set<Map.Entry<K,V>> entries = map.entrySet();for(Map.Entry<K,V> entries : entries){Key = map.getKey(); Value = map.getValue();},Entry 是 Map 的内部接口,是 Map 中存储的数据类型(key = value);
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

class Book {
    private String name;

    public Book(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

public class Test {
    public static void main(String[] args) {
        ArrayList<Book> book = new ArrayList<>();
        book.add(new Book("金瓶梅"));
        book.add(new Book("聊斋志异"));
        book.add(new Book("人间失格"));
        book.add(new Book("失乐园"));

        HashMap<String, ArrayList<Book>> hm = new HashMap<>();
        hm.put("奇书", book);

        System.out.println("1");
        System.out.println(hm);
        System.out.println("size: " + hm.keySet().size());

        Set<String> s = hm.keySet();
        for (String ss : s) {
            System.out.print("2");
            System.out.println(hm.get(ss));
            System.out.println("size: " + hm.get(ss).size());
        }

        Set<Map.Entry<String, ArrayList<Book>>> entries = hm.entrySet();
        for (Map.Entry<String, ArrayList<Book>> e : entries) {
            System.out.print("3");
            System.out.println(e.getKey() + ": " + e.getValue());
            System.out.println("size: " + e.getValue().size());
        }
    }
}
/*
1
{奇书=[金瓶梅, 聊斋志异, 人间失格, 失乐园]}
size: 1
2[金瓶梅, 聊斋志异, 人间失格, 失乐园]
size: 4
3奇书: [金瓶梅, 聊斋志异, 人间失格, 失乐园]
size: 4
 */

a. 转变为集合的遍历

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

public class test {
    public static void main(String[] args) {
        HashMap hm = new HashMap();
        hm.put("001", "apple");
        hm.put("002", "banana");
        //返回映射中包含的项的集合,以便使用迭代器
        Set s = hm.entrySet();
        Iterator it = s.iterator();
        //也可以用增强for
        while (it.hasNext()) {
            //用 Map.Entry 来操作映射的输入
            Map.Entry m = (Map.Entry) it.next();
            System.out.print(m.getKey() + ": ");
            System.out.println(m.getValue());
        }
        //put 旧键可以自动替换相应的值
        hm.put("001", new String("dog"));
        System.out.println(hm.get("001"));
        //返回映射的 键 的集合
        s = hm.keySet();
        it = s.iterator();
        String key = "";
        while (it.hasNext()) {
            //将 k 的集合强转为 String 类型
            key = (String) it.next();
            System.out.println(key + ":" + hm.get(key));
        }
    }
}

b. 存储自定义类型

  • 当给 HashMap 中存放自定义对象时,如果自定义对象作为 key 存在,这时要保证对象唯一,必须复写 key 对象的 hashCode() 和 equals() 方法(与 HashSet 相同);
  • 如果要保证map中存放的key和取出的顺序一致,可以使用 LinkedHashMap 来存放;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

class Student {
    private String name;
    private int age;

    //构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //get/set
    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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

public class test {
    public static void main(String[] args) {
        //1,创建Hashmap集合对象。
        //创建集合时,向上转型和直接创建该形式看使用场景,spring框架已经决定无时无刻不在用多态
        Map<Student, String> map = new HashMap<Student, String>();
        //2,添加元素。
        map.put(new Student("lisi", 28), "上海");
        map.put(new Student("wangwu", 22), "北京");
        map.put(new Student("wangwu", 22), "南京");

        //3,取出元素。键找值方式
        Set<Student> keySet = map.keySet();
        for (Student key : keySet) {
            String value = map.get(key);
            System.out.println(key.toString() + "....." + value);
        }
    }
}
/*
输出
Student{name='lisi', age=28}.....上海
Student{name='wangwu', age=22}.....南京
 */

c. 判断该集合中是否有此键

import java.util.HashMap;
import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        //友情提示
        System.out.println("请录入一个字符串:");
        String line = new Scanner(System.in).nextLine();
        // 定义 每个字符出现次数的方法
        findChar(line);
    }

    private static void findChar(String line) {
        //1:创建一个集合 存储  字符 以及其出现的次数
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        //2:遍历字符串
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            //判断 该字符 是否在键集中
            if (!map.containsKey(c)) {//说明这个字符没有出现过
                //那就是第一次
                map.put(c, 1);
            } else {
                //先获取之前的次数
                Integer count = map.get(c);
                //count++;
                //再次存入  更新
                map.put(c, ++count);
            }
        }
        System.out.println(map);
    }
}
/*
输出
请录入一个字符串:
adfafsd
{a=2, s=1, d=2, f=2}
 */
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值