java双列集合

Map

1.1概述

  • Map:双列集合的顶层接口

  • Map:描述的就是一个数据(key)到另一个数据(value)的对应关系

    • 一个数据(key):就是有规律的,容易记忆的,简单的一个数据

    • 一个数据(value):没有规律的,不容易记忆的,复杂的一个数据

    • 大多数都是根据key来寻找value

  • Map的特点:

    • Key(键)是唯一的

    • Value(值)不是唯一的

  • Map和Collection的区别:

    • Map是双列集合

    • Collection是单列集合

    • Map的键是唯一的,Collection中的Set子接口中的元素是唯一的

    • Map的所有操作是针对《键》有效,Collection中的set子接口中的操作针对《元素》有效

1.2Map中的常用方法

  • 增加键值对:

    • put(K key, V value)

  • 删除方法:

    • 根据给定的键,删除对应的键值对:

      • remove (K key)

      • 清空集合:clear()

  • 获取方法:

    • 获取集合的大小:size()

    • 获取键对应的值,根据给定的键,获取对应的值:V get(K key)

  • 判断方法:

    • 判断集合中是否存在某个键:containsKey(Object obj)

    • 判断集合中是否存在某个值:containsValue(Object obj)

  • 修改方法:

    • 根据给定的键,修改对应的值:put(K key, V value)

      • 如果在集合中已经存在key这个键,那么使用put方法,就是修改其对应的值

      • 如果集合中不存在key这个键,那么使用put方法,就是在集合中增加了一个键值对

代码示例:
import java.util.HashMap;
import java.util.Map;
/**
 *Map中的常用方法
 */
public class Simple01 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        map.put("c", 4);
        System.out.println(map);
        map.remove("a");
        System.out.println(map);
        map.clear();
        System.out.println(map);
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        map.put("d", 4);
        System.out.println(map.size());
        Integer value = map.get("c");
        System.out.println(value);
        boolean b = map.containsKey("bb");
        System.out.println(b);
        boolean b1 = map.containsValue(4);
        System.out.println(b1);
        map.put("a", 11);
        System.out.println(map.get("a"));
        map.put("aa", 111);
        System.out.println(map);
    }
}
​

1.3 Map集合的第一种遍历思路【熟练掌握】

  • 获取Map集合中的所有键,放到一个Set集合中,遍历该Set集合,获取到每一个键,根据键再来获取对应的值。【根据键获取值】

  • 获取Map集合中的所有键并存入Set

    Set<K>  keySet()    //k是你map中键的类型,Set<String> set = map.keySet();

  • 遍历Set集合的两种方法:

    • 迭代器

    • 增强for循环

  • 拿到每个键之后,获取对应的值 V get(K key)

  • 特点: 获取了所有的键的集合之后,仍然要依赖原来的Map集合

代码示例:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
​
/**
 * Map集合的第一种遍历思路【熟练掌握】
 */
​
public class Simple02 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("aaa", 111);
        map.put("bbb", 222);
        map.put("ccc", 333);
        map.put("ddd", 444);
        System.out.println(map);
        // test1(map);//第一种遍历思路的第一种遍历方式迭代器(map)
        test2(map);// 第一种遍历思路的第二种遍历方式增强for(map)
    }
​
    // 第一种遍历思路的第一种遍历方式迭代器(map)
    public static void test1(Map<String, Integer> map) {
        Set<String> set = map.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = it.next();
            System.out.println("key是:" + key + "---value是:" + map.get(key));
        }
    }
        // 第一种遍历思路的第二种遍历方式增强for(map)
    public static void test2(Map<String, Integer> map) {
        Set<String> set = map.keySet();
        for (String key : set) {
            System.out.println("key是:" + key + "---value是:" + map.get(key));
        }
    }
}

1.4 Map集合的第二种遍历思路【熟练掌握】

  • 获取Map集合中的所有键值对对象(Entry)到Set集合中,遍历Set集合,拿到的是每个键值对对象(Entry),从这个对象中分别获取键和值【根据键值对对象获取键和值】

  • 根据Map集合获取所有的键值对对象,到一个Set集合中

  • Set<Map.Entry<K, V>>   entrySet()   Set<Map.Entry<String, String>> set = map.entrySet();

  • 遍历Set集合,两种遍历方式

    • 迭代器

    • 增强for循环

  • 获取到某个键值对对象

  • Entry是Map接口中的内部接口,访问的方式:Map.Entry

    • Entry:入口、条目、登记记录

    • Entry的常用方法:

      • getKey()获取当前键值对对象的键

      • getValue()获取当前键值对对象的值

代码示例:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
​
/**
 * Map集合的第二种遍历思路【熟练掌握】
 */
public class Simple03 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("username", "zhangsan");
        map.put("password", "123456");
        map.put("nickname", "miaomi");
        System.out.println(map);
        test1(map)
        test2(map);
​
    }
​
    //迭代器遍历Set集合
    public static void test1(Map<String, String> map) {
        Set<Map.Entry<String, String>> set = map.entrySet();
        System.out.println(set);
        Iterator<Map.Entry<String, String>> iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            String key = next.getKey();
            String value = next.getValue();
            System.out.println("键是:" + key + "---值是:" + value);
​
        }
    }
​
    // 增强for循环遍历Set(map)
    public static void test2(Map<String, String> map) {
        Set<Map.Entry<String, String>> set = map.entrySet();
        for (Map.Entry<String, String> st : set) {
            System.out.println("键是:" + st.getKey() + "----值是:" + st.getValue());
        }
    }
}

1.5 HashMap

HashMap 的底层实现方式为哈希表,是 HashSet 的实现原理。

image-20230209234735887

  • 就是Map集合使用哈希表的存储方式的一种实现类

  • HashMap存储的是jdk中提供的类型的键,就可以直接保证键的唯一性

  • HashMap中存储的键,是自定义类型(比如下方代码Person),无法保证键的唯一性,原因:虽然都是zhangsan对象,但是这些对象并不是相同的对象,这些对象的哈希值计算结果各不相同,就说明一定不是相同的对象,所以无法保证键的唯一,重写hashCode和equals方法说明:HashMap的键的唯一性和HashSet的元素的唯一性,保证方式都一样

  • HashMap和HashSet的关系:

    • HashSet是由HashMap实现出来的,HashSet就是HashMap的键的那一列

    • 将HashMap中的值的那一列隐藏掉,就变成了HashSet

  • 示例代码:

import java.util.HashMap;
import java.util.Objects;
​
/**
 * HashMap;
 */
public class Simple04 {
​
    public static void main(String[] args) {
        HashMap<Person, String> hm = new HashMap<>();
        hm.put(new Person("张三", 23), "北京");
        hm.put(new Person("张三", 23), "上海");
        hm.put(new Person("张三", 23), "广州");
        System.out.println(hm);
        test1_HashMap存储jdk的键();
    }
​
    private static void test1_HashMap存储jdk的键() {
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("abc", 1);
        hm.put("abc", 3);
        hm.put("ab", 2);
        hm.put("ab", 4);
        System.out.println();
        System.out.println("*******************");
        System.out.println();
        System.out.println(hm);
    }
}
​
class Person {
    String name;
    int age;
​
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }
​
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
​
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

1.6 LinkedHashMap

  • 是HashMap的一个子类

  • 实现原理哈希表+链表

  • 和HashMap不同之处:具有可预知的迭代顺序,存储键值对的顺序和遍历集合时取出键值对的顺序一致。

  • 代码示例:

import java.util.LinkedHashMap;
​
/**
 * LinkedHashMap
 */
public class Simple05 {
​
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
        lhm.put("aa", 3);
        lhm.put("bb", 3);
        lhm.put("cc", 2);
        lhm.put("dd", 4);
        System.out.println(lhm);
    }
}

1.7 HashMap和Hashtable的关系

  • HashMap和Hashtable都是用于存储键和值的对应关系,都是Map的实现类,都是使用哈希表的方式存储。

  • 不同点:

    • 版本不同,Hashtable是jdk1.0版本出现的,HashMap是jdk1.2版本出现的

    • 线程安全性不同,Hashtable是线程安全的,HashMap是线程不安全的

    • Hashtable不能存储null键null值,HashMap可以存储null键null值

  • 代码示例:

import java.util.HashMap;
import java.util.Hashtable;
​
/**
 * HashMap和Hashtable的关系
 */
public class Simple06 {
    public static void main(String[] args) {
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put(null, 0);//键可以存null值
        hm.put("1", null);//值可以存null值
        // hm.put(null, null);//键值可以存null值
        System.out.println(hm);
        test1_Hashtable存储null键null值();
    }
​
    public static void test1_Hashtable存储null键null值() {
        //Hashtable 不可以存储null键值
        Hashtable<String, Integer> ht = new Hashtable<>();
        ht.put("abc", 3);
        ht.put(null, 0);
        ht.put("", null);
        ht.put(null, null);
        System.out.println(ht);
    }
}

Collections集合工具类

  • java.utils.Collections是集合工具类,用来对集合进行操作。工具类的使用方式是类名.方法 比如Collections.sort(list)

  • 常用方法如下:

    • max

    • min

    • addAll

    • reverse

    • shuffle

public static void test1() {
    ArrayList<Integer> list = new ArrayList<>();
    list.add(11);
    list.add(33);
    list.add(55);
    System.out.println(Collections.max(list));
    System.out.println(Collections.min(list));
    Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8);
    System.out.println(list);
    Collections.reverse(list);
    System.out.println(list);
    Collections.shuffle(list);
    System.out.println(list);
}
  • sort 接口实现

public class CollectionsUtil {
    public static void main(String[] args) {
        test2();
    }

    public static void test2() {
        /*
         *   java.utils.Collections是集合工具类,用来对集合进行操作。
         *   工具类的使用方式是类名.方法 比如Collections.sort(list)
         *   注意被排序的集合里面存储的元素必须要实现Comparable接口,并重写接口中
         *   的Compare To 定义排序的规则
         *   像案例中的String ,Integer 默认已经实现了Comparable接口
         *   但是如果是自定义类就需要手动实现Comparable接口并指定泛型。
         *   Compare To 定义排序的规则:
         *   this.属性 - 参数.属性 :升序 ,反之降序
         *
         * */
        ArrayList<Integer> list1 = new ArrayList<>();
        Collections.addAll(list1, 1, 44, 55, 22, 12, -45, 0);
        Collections.sort(list1);
        System.out.println(list1);// 默认升序
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2, "a", "b", "aa", "c", "bb");
        Collections.sort(list2);
        System.out.println(list2);// 默认升序
        ArrayList<Animal> list3 = new ArrayList<>();
        list3.add(new Animal("佩奇", 3));
        list3.add(new Animal("艾米丽", 5));
        list3.add(new Animal("苏西", 2));
        Collections.sort(list3);
        System.out.println(list3);
    }

}

class Animal implements Comparable<Animal> {
    private String name;
    private int age;

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

    public Animal() {
    }

    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;
    }

// 这里不需要重写hashcode 和 equals 方法,因为我们没用set;

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

    @Override
    public int compareTo(Animal o) {
        //        return this.getAge() - o.getAge();// 按年龄升序
        return o.getAge() - this.getAge();// 按年龄降序

    }
}
  • sort 匿名内部类

public class CollectionsUtil {
    public static void main(String[] args) {
        test3();
    }

    public static void test3() {
        /*
         * Comparator 和 Comparable区别
         * Comparable区别是自己和别人(参数)比较,需要实现Comparable接口,重写ComparaeTo方法
         * Comparator相当于找一个第三方的裁判,比较2个参数的大小,需要使用匿名内部类
         * */


        ArrayList<Animal> list4 = new ArrayList<>();
        list4.add(new Animal("a佩奇", 3));
        list4.add(new Animal("b艾米丽", 5));
        list4.add(new Animal("a苏西", 5));
//        Collections.sort(list4, new Comparator<Animal>() {
//            @Override
//            public int compare(Animal o1, Animal o2) {
//                return o1.getAge() - o2.getAge();
//            }
//        });

        Collections.sort(list4, new Comparator<Animal>() {
            @Override
            public int compare(Animal o1, Animal o2) {
                // 按年龄排序
                int result = o1.getAge() - o2.getAge();
                // 如果年龄相同按姓名排序
                if (result == 0) {
                    result = o1.getName().charAt(0) - o2.getName().charAt(0);
                }
                return result;
            }
        });
        System.out.println(list4);
    }

}

class Animal {
    private String name;
    private int age;

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

    public Animal() {
    }

    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;
    }

// 这里不需要重写hashcode 和 equals 方法,因为我们没用set;

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

White-Camellia

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

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

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

打赏作者

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

抵扣说明:

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

余额充值