java学习记录十五:集合二Collections、Set、Map

一、Collections工具类

一、解释

java.utils.Collections是集合工具类,用来对集合进行操作。注意和Collection集合区分。集合和类的区分。
类是数据类型,集合是保存数据的,数据有数据类型。

二、常用方法

1.打乱集合顺序

 //public static void shuffle(List<?> list) :打乱集合顺序。

// 创建List集合,限制集合中元素的类型为Integer类型
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        //这边自动装箱,int变成integer
        list.add(300);
        list.add(100);
        list.add(200);
        list.add(500);
        list.add(400);

        System.out.println("打乱顺序之前的集合:"+list);// [300, 100, 200, 500, 400]
        // 打乱顺序
        Collections.shuffle(list); // 随机打乱顺序
        System.out.println("打乱顺序之后的集合:"+list);// [500, 300, 100, 200, 400]

2.按照默认规则排序

默认规则是从小到大,是升序。这是事先写好的规则,需要排序的集合元素所属的类需要实现重写Comparable接口,重写compareTo方法,在compareTo方法指定排序。

//public static <T> void sort(List<T> list)`:将集合中元素按照默认规则排序。
// 创建List集合,限制集合中元素的类型为Integer类型
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(300);
        list.add(100);
        list.add(200);
        list.add(500);
        list.add(400);

        System.out.println("排序之前的集合:"+list); // [300, 100, 200, 500, 400]
        // 将集合中元素按照默认规则排序
        Collections.sort(list);
        System.out.println("排序之后的集合:"+list); // [100, 200, 300, 400, 500]

模拟重写compareTo方法

public class Student implements Comparable<Student>{
    int age;

    public Student(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
  //重写conpareTo方法
    @Override
    public int compareTo(Student o) {
        // 指定排序规则
        // 前减后  升序
        // 后减前  降序
        // 前:this  后: 参数o
        //按什么排序,就以什么计算
        //这里是年龄来计算
        return this.age - o.age;// 升序
    }
}

     // 创建List集合,限制集合中元素的类型为Student类型
        List<Student> list1 = new ArrayList<>();

        // 往集合中添加元素
        Student stu1 = new Student(19);
        Student stu2 = new Student(18);
        Student stu3 = new Student(20);
        Student stu4 = new Student(17);
        list1.add(stu1);
        list1.add(stu2);
        list1.add(stu3);
        list1.add(stu4);
        System.out.println("排序之前的集合:"+list1);
        // 将集合中元素按照默认规则排序
        Collections.sort(list1);
        System.out.println("排序之后的集合:"+list1);


3.按指定规则排序

这样可以在使用的时候再确定按什么排序。上面的排序写在类中就写死了。

//public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
//Comparator是一个接口,不能创建对象,所以用匿名内部类来实现比较的方法
//参数是接口或类时,就可以想到匿名内部类,尤其是接口不能创建对象,只能用匿名内部类
 // 创建List集合,限制集合中元素的类型为Integer类型
        List<Integer> list = new ArrayList<>();

        // 往集合中添加元素
        list.add(300);
        list.add(100);
        list.add(200);
        list.add(500);
        list.add(400);

        System.out.println("排序之前的集合:" + list); // [300, 100, 200, 500, 400]
        // 将集合中元素按照指定规则排序---->降序
        //new Comparator<Integer>(){}是匿名内部类
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 指定排序规则
                // 前减后  升序
                // 后减前  降序
                // 前: 第一个参数o1  后:第二个参数o2
                return o2 - o1;
            }
        });
        System.out.println("排序之后的集合:" + list); // [500, 400, 300, 200, 100]

        // 将集合中元素按照指定规则排序---->升序
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        System.out.println("排序之后的集合:" + list);// [100, 200, 300, 400, 500]

        System.out.println("=======================================");

        // 创建List集合,限制集合中元素的类型为Student类型
        List<Student> list1 = new ArrayList<>();

        // 往集合中添加元素
        Student stu1 = new Student(19);
        Student stu2 = new Student(18);
        Student stu3 = new Student(20);
        Student stu4 = new Student(17);
        list1.add(stu1);
        list1.add(stu2);
        list1.add(stu3);
        list1.add(stu4);
        System.out.println("排序之前的集合:" + list1);
        // 将集合中元素按照指定规则排序-->按照年龄降序排序
        Collections.sort(list1, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 指定排序规则
                // 前减后  升序
                // 后减前  降序
                // 前: 第一个参数o1  后:第二个参数o2
                return o2.age - o1.age;
            }
        });
        System.out.println("排序之后的集合:" + list1);//是降序

        // 将集合中元素按照指定规则排序-->按照年龄升序排序
        Collections.sort(list1, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 指定排序规则
                // 前减后  升序
                // 后减前  降序
                // 前: 第一个参数o1  后:第二个参数o2
                return o1.age - o2.age;
            }
        });
        System.out.println("排序之后的集合:" + list1);//是升序
    }
}

4.批量添加元素

//public static <T> boolean addAll(Collection<T> c, T... elements)  `:往集合中添加一些元素。

        // 创建ArrayList集合,限制集合元素的类型为String类型
        ArrayList<String> list = new ArrayList<>();

        // 往list集合中添加批量元素
        Collections.addAll(list,"2","A","K","Q","J","10","9","8","7","6","5","4","3");
        System.out.println(list)

二、可变参数

一、解释

JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化

二、写法

//修饰符 返回值类型 方法名(参数类型... 形参名){  }

    // 定义一个方法,可以接收5个int类型的数
    public static void method1(int num1,int num2,int num3,int num4,int num5){// 接收5个具体的数

    }
   // 定义一个方法,可以接收5个int类型的数
    public static void method2(int[] arr){// 接收数组
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
       // 定义一个方法,可以接收5个int类型的数
    public static void method3(int... nums){
        // 使用:把nums可变参数当成数组使用
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums[i]);
        }
    }
    method3(10,20,30,40,50);
    int[] arr = {10,20,30,40,50};
      method3(arr);
      //两种格式都能使用。进来后都会变成数组。

三、注意事项

  • 1.一个方法只能有一个可变参数
  • 2.如果方法中有多个参数,可变参数要放到最后。

三、set接口

一、解释

Set接口:也称Set集合,但凡是实现了Set接口的类都叫做Set集合
特点: 元素无索引,元素不可重复(唯一)

  • HashSet集合: 实现类–元素存取无序
  • LinkedHashSet集合:实现类–元素存取有序
  • TreeSet集合:实现类–> 对元素进行排序
  • 注意:
    1.Set集合没有特殊的方法,都是使用Collection接口的方法
    2.Set集合没有索引,所以遍历元素的方式就只有: 增强for循环,或者迭代器
    每个接口都可以有不同的实现类,来实现不同 的功能,创建不同的对象.

二、HashSet集合

一、解释

java.util.HashSetSet接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不能保证不一致)。

public class Test {
    public static void main(String[] args) {
        /*
            HashSet集合: 元素存取无序,元素不可重复,元素无索引
         */
        // 创建HashSet集合对象,限制集合元素的类型为String
        HashSet<String> set = new HashSet<>();
        // 往集合中添加元素
        set.add("nba");
        set.add("cba");
        set.add("bac");
        set.add("abc");
        set.add("nba");
        System.out.println(set);// [cba, abc, bac, nba],顺序和存储的顺序不一致
    }
}

二、HashSet集合存储数据和保持数据唯一性原理

  • HashSet集合存储数据的结构—哈希表结构
    哈希表结构:
    jdk8以前: 数组+链表
    jdk8以后: 数组+链表+红黑树
    链表元素个数没有超过8: 数组+链表
    链表元素个数超过8: 数组+链表+红黑树
  • HashSet集合保证元素唯一的原理–依赖Object类的两个方法,hashCode()和equals()方法
    1.当存储元素的时候,就会调用该元素的hashCode()方法计算该元素的哈希值,哈希值模16,得到一个余数,得到的结果是1到15,在比较对应位置上有没有元素,没有就存进去,这就导致存和取的顺序不一样了。
    2.判断该哈希值对应的位置上,是否有元素:
    3.如果该哈希值对应的位置上,没有元素,就直接存储
    4.如果该哈希值对应的位置上,有元素,说明产生了哈希冲突
    5.产生了哈希冲突,就得调用该元素的equals方法,与该位置上的所有元素进行一一比较:
    如果比较的时候,有任意一个元素与该元素相同,那么就不存储
    如果比较完了,没有一个元素与该元素相同,那么就直接存储,要是这个链表的元素到了8个,就会变成红黑树。
  • 补充:
    Object类: hashCode()和equals()方法;
    hashCode():Object类中的hashCode()方法是根据地址值计算哈希值
    equals方法():Object类中的equals()方法是比较地址值

三、hashset存储自定义类型

重写hashcode方法和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一.,不然的话,对象属性值相同的值还是会存进去,开发中我们认为对象属性相同就是同一个对象。不管它的地址值

public class Person{
    /**
     * 姓名
     */
    public String name;
    /**
     * 年龄
     */
    public int age;

    public Person() {
    }

    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 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);
    }
}
public class Demo {
    public static void main(String[] args) {
        // 创建多个Person对象
        Person p1 = new Person("张三", 18);
        Person p2 = new Person("李四", 38);
        Person p3 = new Person("王五", 28);
        Person p4 = new Person("张三", 18);

        // 创建HashSet集合对象,限制集合中元素的类型为Person
        HashSet<Person> set = new HashSet<>();

        // 往集合中添加Person对象
        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4);

        // 遍历打印集合中的元素
        for (Person p : set) {
            System.out.println(p);
        }

        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p3.hashCode());
        System.out.println(p4.hashCode());
    }
}

三、linkedHashSet集合

一、解释

HashSet保证元素唯一,可是元素存放进去是没有顺序的,要保证有序,可以使用LinkedHashSet,在HashSet下面有一个子类java.util.LinkedHashSet,它是链表和哈希表组合的一个数据存储结构,由哈希表保证元素唯一,由链表保证元素存取有序

// 创建LinkedHashSet集合,限制集合中元素的类型为Integer类型
    LinkedHashSet<Integer> set = new LinkedHashSet<>();// 存取有序
    //HashSet<Integer> set = new HashSet<>();// 存取无序

    // 往集合中存储数据
    set.add(300);
    set.add(100);
    set.add(200);
    set.add(500);
    set.add(400);
    set.add(400);

    System.out.println(set);// [300, 100, 200, 500,400]

四、TreeSet集合

一、解释

TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现,其特点为:

  1. 元素唯一
  2. 元素没有索引
  3. 使用元素的自然顺序对元素进行排序,或者根据创建 TreeSet 时提供的 Comparator比较器
    进行排序,具体取决于使用的构造方法
public class Test {
    public static void main(String[] args) {
        /*
            TreeSet集合: 元素无索引,元素唯一,对元素进行排序
              通过构造方法实现排序:
            public TreeSet():根据其元素的自然排序进行排序
                            默认规则排序:集合元素所属的类需要实现Comparable接口,重写compareTo方法,在compareTo方法中指定默认排序规则

             public TreeSet(Comparator<E> comparator):    根据指定的比较器进行排序
                            指定规则排序: 通过传入Comparator接口的实现类对象,在实现类对象中重写compare方法,在compare方法中指定排序规则
         */
        // 按照默认规则排序---->默认升序
        // 创建TreeSet集合,限制集合中元素的类型为Integer类型
        TreeSet<Integer> set = new TreeSet<>();

        // 往集合中存储数据
        set.add(300);
        set.add(100);
        set.add(200);
        set.add(500);
        set.add(400);
        set.add(400);
        System.out.println(set);// [100, 200, 300, 400, 500]

        System.out.println("===========================================");
        // 按照指定规则排序---->降序
        // 创建TreeSet集合,限制集合中元素的类型为Integer类型
        TreeSet<Integer> set1 = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                /*
                    指定排序规则:
                    前减后  升序
                    后减前  降序
                    前:第一个参数  后:第二个参数
                 */
                return o2 - o1;
            }
        });

        // 往集合中存储数据
        set1.add(300);
        set1.add(100);
        set1.add(200);
        set1.add(500);
        set1.add(400);
        set1.add(400);
        System.out.println(set1);// [500, 400, 300, 200, 100]

        System.out.println("===========================================");
        // 按照指定规则排序---->升序
        // 创建TreeSet集合,限制集合中元素的类型为Integer类型
        TreeSet<Integer> set2 = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                /*
                    指定排序规则:
                    前减后  升序
                    后减前  降序
                    前:第一个参数  后:第二个参数
                 */
                return o1 - o2;
            }
        });

        // 往集合中存储数据
        set2.add(300);
        set2.add(100);
        set2.add(200);
        set2.add(500);
        set2.add(400);
        set2.add(400);
        System.out.println(set2);// [100, 200, 300, 400, 500]
    }
}

四、Map集合

一、解释

Map集合是双列集合的顶层,它里面的方法所有双列集合都能使用,collection是单列集合,存储元素是单个单个存储的,双列集合是一对一对存储的。Collection是单列集合,相当于js数组,双列相当于js里的对象。有键名和键值对。

二、Map集合特点

Map<K,V>集合的特点: K用来限制键的类型,V用来限制值的类型
1.Map集合存储元素是以键值对的形式存储,每一个键值对都有键和值
2.Map集合的键是唯一,值可以重复,如果键重复了,那么值就会被覆盖
3.根据键取值,HashSet<E>:存储数据采用的是哈希表结构,保证元素唯一,重写元素所属的类hashCode和eauals方法。

三、Map集合子类

  • HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。
    由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

    • LinkedHashMap<K,V>:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。
      通过链表结构可以保证键值对的存取顺序一致;
      通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

    • TreeMap<K,V>:TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;
      可以对元素的键进行排序,排序方式有两种:自然排序和比较器排序

四、Map集合的常用方法

1.把指定的键与指定的值添加到Map集合中

这个方法也可以做修改方法,因为重复的键,后面的会覆盖前面的

//public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。
    // 创建Map集合,限制键的类型为String,值的类型为String
    //接口不能创建对象,所以用hashMap这个实现类来创建对象
        Map<String, String> map = new HashMap<>();

        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");
        System.out.println(map);// {文章=马伊琍, 谢霆锋=王菲, 黄晓明=杨颖}
        // Map集合键唯一,如果键重复了,值会覆盖
        String v1 = map.put("文章", "姚笛");
        System.out.println("v1:"+v1);// 马伊琍
        System.out.println(map);// {文章=姚笛, 谢霆锋=王菲, 黄晓明=杨颖}
         // Map集合值可以重复
        String v2 = map.put("李亚鹏", "王菲");
        System.out.println("v2:"+v2);// null
        System.out.println(map);// {文章=姚笛, 谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖}
        //使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中; 
       //若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值

2.把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。

//public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
// 删除文章这个键对应的键值对
        String v3 = map.remove("文章");
        System.out.println("被删除键值对的值:"+v3);// 姚笛
        System.out.println(map);// {谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖}

3.根据指定的键,在Map集合中获取对应的值

// 获取黄晓明这个键对应的值
String value = map.get("黄晓明");
System.out.println("value:"+value);// 杨颖

4.判断该集合中是否有此键或此值

containsKey和containsValue

//public boolean containsKey(Object key):判断该集合中是否有此键
       // 判断是否包含指定的键
        System.out.println(map.containsKey("黄晓明"));// true
        System.out.println(map.containsKey("文章"));// false
// 判断是否包含指定的值
        System.out.println(map.containsValue("杨颖"));// true
        System.out.println(map.containsValue("马伊琍"));// false

5.获取Map集合中所有的键,存储到Set集合中。

//public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
       // 获取所有的键
        Set<String> keys = map.keySet();
        System.out.println("keys:"+keys);// [谢霆锋, 李亚鹏, 黄晓明]

6.获取Map集合中所有的值,存储到Collection集合中。

//public Collection<V> values(): 获取Map集合中所有的值,存储到Collection集合中。
     // 获取所有的值
        Collection<String> values = map.values();
        System.out.println("values:"+values);// [王菲, 王菲, 杨颖]

7.获取到Map集合中所有的键值对对象的集合(Set集合)。

//public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
//Entry是Map的内部类,表示set里是Entry类型的对象
//Map.Entry<K,V>:表示键值对对象---把键值对包装成一个对象,该对象的类型就是Entry类型
 // 获取Map集合中所有键值对对象
        Set<Map.Entry<String, String>> set = map.entrySet();
        System.out.println(set);// [谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖]

五、Map集合的遍历

1.根据键找值

  1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:keyset()
  2. 遍历键的Set集合,得到每一个键。
  3. 根据键,获取键所对应的值。方法提示:get(K key)
 public class Demo {
    public static void main(String[] args) {
        // 创建Map集合对象,限制键的类型为String,值的类型为String
        Map<String, String> map = new HashMap<>();
        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");

        // 遍历map集合
        // 获取集合中所有的键  Set<K> keySet()方法
        Set<String> keys = map.keySet();
        // 遍历所有的键的集合
        for (String key : keys) {
            // 在循环中,根据键找值 V get(K key)方法
            String value = map.get(key);
            System.out.println("键:"+key+",值:"+value);
        }
    }
}

2.键值对方式

Entry<K,V>接口:简称Entry项,表示键值对对象,用来封装Map集合中的键值对
Entry<K,V>接口:是Map接口中的内部接口,在外部使用的时候是这样表示: Map.Entry<K,V>

Map集合中提供了一个方法来获取所有键值对对象:
public Set<Map.Entry<K,V>> entrySet()

根据键值对对对象获取键和值:
- public K getKey():获取Entry对象中的键。
- public V getValue():获取Entry对象中的值。

Map遍历方式二:根据键值对对象的方式
1.获取集合中所有键值对对象,以Set集合形式返回。 Set<Map.Entry<K,V>> entrySet()
2.遍历所有键值对对象的集合,得到每一个键值对(Entry)对象。
3.在循环中,可以使用键值对对对象获取键和值 getKey()和getValue()

public class Demo {
    public static void main(String[] args) {
        // 创建Map集合对象,限制键的类型为String,值的类型为String
        Map<String, String> map = new HashMap<>();
        // 往map集合中添加键值对
        map.put("黄晓明", "杨颖");
        map.put("文章", "马伊琍");
        map.put("谢霆锋", "王菲");

        // 获取集合中所有键值对对象  Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<String, String>> entrySet = map.entrySet();

        // 遍历所有键值对对象的集合
        for (Map.Entry<String, String> entry : entrySet) {
            // 在循环中,可以使用键值对对对象获取键和值   getKey()和getValue()
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println("键:"+key+",值:"+value);
        }
    }
}

六、HashMap存储自定义类型

public class Student {
    /**
     * 姓名
     */
    public String name;
    /**
     * 年龄
     */
    public int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        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);
    }
}
public class Demo {
    public static void main(String[] args) {
        // 创建Map集合,指定键的类型为Student,值的类型为String
        HashMap<Student,String> map = new HashMap<>();

        // 创建多个学生对象
        Student stu1 = new Student("张三", 18);
        Student stu2 = new Student("李四", 38);
        Student stu3 = new Student("王五", 28);
        Student stu4 = new Student("张三", 18);

        // 把学生对象作为键,家庭地址作为值,存储到map集合中
        map.put(stu1,"北京");
        map.put(stu2,"上海");
        map.put(stu3,"深圳");
        map.put(stu4,"广州");

        // 打印map集合
        System.out.println(map);
        System.out.println(map.size());// 3
    }
}
  • 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
  • 如果要保证map中存放的key和取出的顺序一致,可以使用java.util.LinkedHashMap集合来存放。

7.LinkedHashMap集合

HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,就要使用LinkedHashMap集合

  • 通过链表结构可以保证元素的存取顺序一致;
  • 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
public class Test {
    public static void main(String[] args) {
        /*
            LinkedHashMap: 元素存取有序,键唯一,值可重复
                - 通过链表结构可以保证元素的存取顺序一致;
                - 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
         */
        // 创建LinkedHashMap集合,限制键的类型为Integer,值的类型为String
        LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
        
        // 往map集合中添加键值对
        map.put(300, "深圳");
        map.put(100, "北京");
        map.put(200, "广州");
        map.put(500, "上海");
        map.put(400, "武汉");
        map.put(400, "深圳");
        System.out.println(map);
    }
}

8.TreeMap集合

TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的键进行排序,排序方式有两种:自然排序比较器排序;到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法;
构造方法

public TreeMap()									使用自然排序
public TreeMap(Comparator<? super K> comparator) 	   通过比较器指定规则排序

public class Test {
    public static void main(String[] args) {
        /*
            TreeMap集合: 键唯一,值可以重复,如果键重复了,值就覆盖,可以根据键对键值对进行排序
                public TreeMap()									根据键按照默认规则进行排序
                public TreeMap(Comparator<? super K> comparator) 	通过比较器指定规则排序
         */
        // 按照键的默认规则排序: ---->升序
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map = new TreeMap<>();

        // 往map集合中添加键值对
        map.put(300, "深圳");
        map.put(100, "北京");
        map.put(200, "广州");
        map.put(500, "上海");
        map.put(400, "武汉");
        map.put(400, "深圳");
        System.out.println(map);

        System.out.println("+=================================");

        // 按照指定规则排序: ---->降序
        // 创建TreeMap集合,限制键的类型为Integer,值的类型为String
        TreeMap<Integer, String> map1 = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                /*
                    前减后: 升序
                    后减前: 降序
                    前:第一个参数  后:第二个参数
                 */
                return o2 - o1;
            }
        });
        // 往map集合中添加键值对
        map1.put(300, "深圳");
        map1.put(100, "北京");
        map1.put(200, "广州");
        map1.put(500, "上海");
        map1.put(400, "武汉");
        map1.put(400, "深圳");
        System.out.println(map1);
    }
}

五、Map集合例子

public class Test {
    public static void main(String[] args) {
        /*
            Map集合练习:输入一个字符串,统计该字符串中每个字符出现次数。
         */
        // 0.输入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String s = sc.nextLine();

        // 1.创建Map集合,键的类型为Character,值的类型为Integer
        HashMap<Character, Integer> map = new HashMap<>();

        // 2.循环遍历字符串
        for (int i = 0; i < s.length(); i++) {
            // 3.在循环中获取遍历出来的字符
            char c = s.charAt(i);
            // 4.判断集合中是否存在该字符的键
            if (map.containsKey(c)) {
                // 6.如果集合中已存在该字符的键,那么就取出该字符键对应的值,然后自增1,作为新的值,重新存储到Map集合中
                Integer value = map.get(c);
                value++;
                map.put(c, value);
            } else {
                // 5.如果集合中不存在该字符的键,那么就该字符作为键,值为1,存储到Map集合中
                map.put(c, 1);
            }
        }
        // 7.循环结束,打印map集合
        System.out.println(map);
    }
}

六、集合嵌套

一、解释

任何集合内部都可以存储其它任何集合

二、list嵌套list

public class Test1 {
    public static void main(String[] args) {
        /*
            集合的嵌套:
                - List嵌套List
                - List嵌套Map
                - Map嵌套Map
            结论:任何集合内部都可以存储其它任何集合
         */
        //  List嵌套List
        // 创建一个List集合,限制元素类型为String
        List<String> list1 = new ArrayList<>();

        // 往集合中添加元素
        list1.add("王宝强");
        list1.add("贾乃亮");
        list1.add("陈羽凡");

        // 创建一个List集合,限制元素类型为String
        List<String> list2 = new ArrayList<>();

        // 往集合中添加元素
        list2.add("马蓉");
        list2.add("李小璐");
        list2.add("白百何");

        // 创建一个List集合,限制元素类型为List集合 (List集合中的元素是List集合)
        List<List<String>> list = new ArrayList<>();
        list.add(list1);
        list.add(list2);

        // 遍历
        for (List<String> e : list) {
            for (String name : e) {
                System.out.println(name);
            }
            System.out.println("=============");
        }

        System.out.println(list);
    }
}

三、list嵌套map

public class Test2 {
    public static void main(String[] args) {
        /*
            List嵌套Map:

         */
        // 创建Map集合对象
        Map<String,String> map1 = new HashMap<>();
        map1.put("it001","迪丽热巴");
        map1.put("it002","古力娜扎");

        // 创建Map集合对象
        Map<String,String> map2 = new HashMap<>();
        map2.put("heima001","蔡徐坤");
        map2.put("heima002","李易峰");

        // 创建List集合,用来存储以上2个map集合
        List<Map<String,String>> list = new ArrayList<>();
        list.add(map1);
        list.add(map2);

        System.out.println(list.size()); // 2

        for (Map<String, String> map : list) {
            // 遍历获取出来的map集合对象
            Set<String> keys = map.keySet();// 获取map集合所有的键
            // 根据键找值
            for (String key : keys) {
                System.out.println(key + ","+ map.get(key));
            }
        }

    }
}

四、Map嵌套Map

public class Test3 {
    public static void main(String[] args) {
        /*
            Map嵌套Map:

         */
        // 创建Map集合对象
        Map<String,String> map1 = new HashMap<>();
        map1.put("it001","迪丽热巴");
        map1.put("it002","古力娜扎");

        // 创建Map集合对象
        Map<String,String> map2 = new HashMap<>();
        map2.put("heima001","蔡徐坤");
        map2.put("heima002","李易峰");

        // 创建Map集合,把以上2个Map集合作为值存储到这个map集合中
        Map<String, Map<String, String>> map = new HashMap<>();

        map.put("传智博客",map1);
        map.put("黑马程序员",map2);

        System.out.println(map.size());// 2

        // 获取map集合中的所有键
        Set<String> keys = map.keySet();
        // 遍历所有的键
        for (String key : keys) {
            // 根据键找值
            Map<String, String> value = map.get(key);
            // 遍历value这个Map集合
            Set<String> keySet = value.keySet();
            for (String k : keySet) {
                String v = value.get(k);
                System.out.println(k+","+v);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值