Map子类--HashMap、LinkedHashMap、TreeMap

HashMap

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

HashMap:是基于哈希表的Map接口实现。哈希表的作用是用来保证键的唯一性的。

public class Stu {
    String name;
    int age;

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

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Stu stu = (Stu) o;

        if (age != stu.age) return false;
        return name != null ? name.equals(stu.name) : stu.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

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

public class HashMapDemo {
    public static void main(String[] args) {
        Map m = new HashMap<Stu,String>();

        m.put(new Stu("lili", 21),"90");
        m.put(new Stu("lili", 21),"80");
        m.put(new Stu("jack", 21),"100");

        Set<Stu> keySet = m.keySet();
        for(Stu key : keySet){
            System.out.println("key="+ key.getName()+",value="+ m.get(key));
        }

        Set<Map.Entry<Stu,String>> entrySet = m.entrySet();
        for(Map.Entry<Stu,String> me : entrySet){
            System.out.println("key="+ me.getKey().getName()+",value="+me.getValue());
        }
    }
}

输出:
key=jack,value=100
key=lili,value=80
key=jack,value=100
key=lili,value=80

键:Student 需要实现hashCode()equals()方法,保证键值唯一。

LinkedHashMap

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

LinkedHashMap:是Map接口的哈希表链表实现,具有可预知的迭代顺序。

  1. 哈希表保证键的唯一性。
  2. 链表保证键的有序(存储和取出的顺序一致)。
public class LinkedHashDemo {
    public static void main(String[] args) {
        Map m = new LinkedHashMap<Stu,String>();

        m.put(new Stu("lili", 21),"90");
        m.put(new Stu("lili", 21),"80");
        m.put(new Stu("jack", 21),"100");

        Set<Stu> keySet = m.keySet();
        for(Stu key : keySet){
            System.out.println("key="+ key.getName()+",value="+ m.get(key));
        }
    }
}

输出:
key=lili,value=80
key=jack,value=100

LinkedHashMap可以保证存储有序。

Hashtable

public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable

Hashtable:线程安全,效率低。不允许 null 键和 null 值
HashMap:线程不安全,效率高。允许 null 键和 null 值

public class HashtableDemo {
    public static void main(String[] args) {
        // HashMap<String, String> hm = new HashMap<String, String>();
        Hashtable<String, String> hm = new Hashtable<String, String>();

        hm.put("it001", "hello");
        // hm.put(null, "world"); //NullPointerException
        // hm.put("java", null); // NullPointerException

        System.out.println(hm);
    }
}

TreeMap

public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable

HashMap:是基于红黑树的Map接口的实现。

  • 保证元素排列方式:
    • 1、自然排序(元素具备比较性):元素所属的类实现Comparable接口。
    • 2、比较器排序(集合具备比较性):集合构造方法接收Comparator的实现类对象。

小知识:TreeMap没有直接实现Map接口。

自然排序

public class Stu implements Comparable{
    String name;
    int age;

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

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    @Override
    public int compareTo(Object obj) {
        Stu stu = (Stu) obj;
        int num1 = this.getName().compareTo(stu.getName());
        int num2 = num1 == 0 ? this.getAge() - stu.getAge() : num1;

        return num2;
    }

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

public class TreeMapDemo {
    public static void main(String[] args) {
        // 创建集合对象
        TreeMap<Stu, String> tm = new TreeMap<Stu, String>();

        // 创建元素并添加元素
        tm.put(new Stu("lili", 21),"90");
        tm.put(new Stu("lili", 21),"80");
        tm.put(new Stu("jack", 21),"100");

        // 遍历集合
        Set<Stu> keySet = tm.keySet();
        for(Stu key : keySet){
            System.out.println("key="+ key.getName()+",value="+ tm.get(key));
        }
    }
}

输出:
key=jack,value=100
key=lili,value=80

比较器排序

public class Stu{
    String name;
    int age;

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

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

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

public class TreeMapDemo {
    public static void main(String[] args) {
        // 创建集合对象
        TreeMap<Stu, String> tm = new TreeMap<Stu, String>(new Comparator<Stu>() {
            @Override
            public int compare(Stu stu, Stu t1) {
                int num1 = stu.getName().compareTo(t1.getName());
                int num2 = num1 == 0 ? stu.getAge() - t1.getAge() : num1;

                return num2;
            }
        });

        // 创建元素并添加元素
        tm.put(new Stu("lili", 21),"90");
        tm.put(new Stu("lili", 21),"80");
        tm.put(new Stu("jack", 21),"100");

        // 遍历集合
        Set<Stu> keySet = tm.keySet();
        for(Stu key : keySet){
            System.out.println("key="+ key.getName()+",value="+ tm.get(key));
        }
    }
}

输出:
key=jack,value=100
key=lili,value=80

需求:“aababcabcdabcde”,获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)

思路:遍历输入的字符串,然后逐词查询集合是否为null,如果返回null,往HashMap添加;如果返回非空,该字符对应个数加一,然后再添加(修改);

public class HashMapTest {
    public static void main(String[] args) {
        // 定义一个字符串(可以改进为键盘录入)
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String line = sc.nextLine();

        // 定义一个TreeMap集合
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();

        //把字符串转换为字符数组
        char[] chs = line.toCharArray();

        //遍历字符数组,得到每一个字符
        for(char ch : chs){
            //拿刚才得到的字符作为键到集合中去找值,看返回值
            Integer i =  tm.get(ch);

            //是null:说明该键不存在,就把该字符作为键,1作为值存储
            if(i == null){
                tm.put(ch, 1);
            }else {
                //不是null:说明该键存在,就把值加1,然后重写存储该键和值
                i++;
                tm.put(ch,i);
            }
        }

        //定义字符串缓冲区变量
        StringBuilder sb=  new StringBuilder();

        //遍历集合,得到键和值,进行按照要求拼接
        Set<Character> set = tm.keySet();
        for(Character key : set){
            Integer value = tm.get(key);
            sb.append(key).append("(").append(value).append(")");
        }

        //把字符串缓冲区转换为字符串输出
        String result = sb.toString();
        System.out.println("result:"+result);
    }
}

输出:
请输入一个字符串:
aababcabcdabcde
result:a(5)b(4)c(3)d(2)e(1)

利用put()方法两个功能:1、添加元素不存在,直接添加;2、添加元素存在,替换原先值,并且返回原先值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会叫的狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值