在生活中有许多带有映射关系的数据,比如一个身份证号就对应一个人,那么我们如何存储这样的数据呢,在Java中为我们提供了另外的集合:Map集合。Map集合常用的实现类有( HashMap, Hashtable, LinkedHashMap TreeMap Properties
  Map集合属于双列集合,是通过键来找值;在Map集合中键不能重复,每个键也只能对应一个值。如果键相同的时候,就会把旧值覆盖,然后返回旧值。还有就是Map集合中的数据结构只和键有关,和值无关,值只是键映射的一个数据;键是怎样的顺序,值就为相应的顺序。

一、Map集合的功能

1、添加功能
  • V put(K key,V value):添加元素。这个其实还有另一个功能就是替换。如果键是第一次存储,就直接存储元素,返回null;如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值。
2、删除功能
  • void clear():移除所有的键值对元素
  • V remove(Object key):根据键删除键值对元素,并把值返回
3、判断功能
  • boolean containsKey(Object key):判断集合是否包含指定的键
  • boolean containsValue(Object value):判断集合是否包含指定的值
  • boolean isEmpty():判断集合是否为空
4、获取功能
  • Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
  • V get(Object key):根据键获取值
  • Set keySet():获取集合中所有键的集合
  • Collection values():获取集合中所有值的集合

二、HashMap集合

  HashMap集合是Map集合的实现类。HashMap允许键为 null 和值为 null。一般我们都使用HashMap来实现Map集合,因为HashMap 集合实现 Map 集合添加元素和删除映射关系效率更高

import java.util.HashMap;
public class MyTest {
    public static void main(String[] args) {       
        HashMap<String, String> map = new HashMap<>();
        String v = map.put("1", "张三");
        //第一次存储键 "1",返回null
        System.out.println(v);
        //当发生键相同的时候,值就会覆盖,返回的是旧值
        v = map.put("1", "李四");
        System.out.println(v);
        map.put("2", "李李");
        map.put("3", "王王");
        map.put("4", "冯冯");
        System.out.println(map);
    }
}
//运行结果为
null
张三
{1=李四, 2=李李, 3=王王, 4=冯冯}

  如果我们想要对Map集合进行遍历我们可以通过键来找值。还可以把这个Map集合中的键值对放到一个Set集合中然后分别获取键和值来进行输出。

  方式一(通过键找值)

public class MyTest3 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //获取hashMap集合的键
        Set<Integer> integers = hashMap.keySet();      
        for (Integer key : integers) {
            System.out.println(key + "===" + hashMap.get(key));
        }
    }
}

  方式二(分别获取键和值)

public class MyTest4 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //entrySet() 获取键值对 放到Set集合里面去
        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        //K getKey ()
        //返回与此项对应的键。
        //V getValue ()
        //返回与此项对应的值。
        for (Map.Entry<Integer, String> entry : entries) {
            //System.out.println(entry);
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}

  当HashMap集合存储的键为自定义类的时候我们还需要重写 hashCode方法 和 equals 方法来保证键的唯一。

三、TreeMap集合

  TreeMap集合的键数据结构为红黑树,这样可以保证键的唯一性和可排序,排序也分为自然排序和比较器排序(方式和TreeSet一样)。定义一个学生类,并进行测试

Student类

import java.util.Objects;
public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @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 int compareTo(Student o) {
        int num=this.age-o.age;
        int num2=num==0?this.name.compareTo(o.name):num;
        return num2;
    }
}

自然排序

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MyTest {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>();
        treeMap.put(new Student("张三0", 23), "111");
        treeMap.put(new Student("张三0", 23), "222");
        treeMap.put(new Student("张三0", 23333), "222");
        treeMap.put(new Student("张三1", 24), "444");
        treeMap.put(new Student("张三2", 26), "555");
        treeMap.put(new Student("张三3", 25), "666");
        treeMap.put(new Student("张三4", 28), "777");

        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}

比较器排序

import java.util.Comparator;
import java.util.TreeMap;
public class MyTest2 {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getAge()-s2.getAge();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return -num2;
            }
        });
        treeMap.put(new Student("张三0", 23), "111");
        treeMap.put(new Student("张三0", 23), "222");
        treeMap.put(new Student("张三0", 23333), "222");
        treeMap.put(new Student("张三1", 24), "444");
        treeMap.put(new Student("张三2", 26), "555");
        treeMap.put(new Student("张三3", 25), "666");
        treeMap.put(new Student("张三4", 28), "777");
        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "===" + value);
        }
    }
}

  上面的代码分别是TreeMap的两种排序方法。 TreeMap集合的线程是不安全的但是效率比较高。

四、Collections类

  Collections类是针对集合操作的工具类,它有多种成员方法来对集合进行操作。

1. public static void sort(List list): 排序,默认按照自然顺序
2. public static int binarySearch(List<?> list,T key): 二分查找
3. public static T max(Collection<?> coll): 获取最大值
4. public static void reverse(List<?> list): 反转
5. public static void shuffle(List<?> list): 随机置换(随机打乱顺序,如斗地主的洗牌阶段)

实例代码如下:

import java.util.ArrayList;

import java.util.Collections;
public class MyTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(1002);
        list.add(1030);
        list.add(1050);
        list.add(100);
        //对list集合排序
        Collections.sort(list);
        System.out.println(list);
       //通过二分查找获取索引
        int i = Collections.binarySearch(list, 1050);
        System.out.println(i);

        System.out.println(Collections.max(list));   //获取最大值
        System.out.println(Collections.min(list));   //获取最小值
        Collections.reverse(list);//反转集合中的元素
        System.out.println(list);

        Collections.shuffle(list);//随机打乱集合中元素的顺序
        System.out.println(list);
    }
}
//运行结果为
[100, 100, 1002, 1030, 1050]
4
1050
100
[1050, 1030, 1002, 100, 100]
[100, 1050, 1030, 1002, 100]

  此类完全由在 Collection 上进行操作或返回 Collection 的静态方法组成,所有可以通过类名直接调用方法。