java中Collections、Map集合、HashMap集合、LinkedHashMap集合、Hashtable集合、List/Map/Set接口静态方法of

  • Post author:
  • Post category:java



Collections:集合工具类:

Collections是一个集合的工具类,通过此类可以调用操作集合的api,但是只能操作list结合,不能操作set集合,如下:

Person类:用于集合存储自定义元素时创建自定义对象:

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

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public Person() {
    }

    // 重写Comparable中的compareTo方法
    @Override
    public int compareTo(Person o) {
        return this.getAge() - o.getAge(); // 升序,反过来减就是降序
    }

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

Student类:另一个用于集合存储自定义元素时创建自定义对象:

public class Student {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

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

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

    public Student() {
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Collections工具方法使用:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// Collections是集合工具类:操作集合的工具,具体看下面案例:
public class CollectionClass {
    public static void main(String[] args) {
        ArrayList<String> ls = new ArrayList<>();
        ls.add("a");
        ls.add("b");
        ls.add("c");
        // 1.addAll() 它是一个静态方法,可以直接通过Collection点出来使用,用法是给一个集合一次添加多个元素:
        Collections.addAll(ls, "d", "e", "f");
        System.out.println(ls); // [a, b, c, d, e, f]
        // 2.shuffl() 打乱集合的顺序:
        Collections.shuffle(ls);
        System.out.println(ls); // [a, f, b, c, e, d] ,每次执行结果都不一样,因为每次都会被打乱

        ArrayList<Integer> lsint = new ArrayList<>();
        Collections.addAll(lsint, 1, 3, 5, 2, 4);
        // 3.sort对list集合进行默认排序(默认升序排序,它既可以排序数字,也可以排序字符或字符串,字符或字符串将安装ascall码顺序排序),注意,只能操作list集合,不能操作set集合和JavaScript中sort类似:
        Collections.sort(lsint);
        System.out.println(lsint); // [1, 2, 3, 4, 5]

        // 4.对自定义类进行排序:对自定义类创建的元素进行排序时,必须重写接口Comparable中compareTo方法 指定排序规则
        ArrayList<Person> listp = new ArrayList<>();
        Person p1 = new Person(22, "小明");
        Collections.addAll(listp, p1, new Person(19, "王佳人"), new Person(20, "刘琦"));
        Collections.sort(listp); // 对自定义对象默认是不能排序的,因为不知道以什么为根据进行排序,不管是对数字或是字符串进行排序,其都调用了接口Comparable,对其进行排序,此时想要对自定义类创建的对象进行排序,那么就得重写此接口:
        System.out.println(listp); // [Person{age=19, name='王佳人'}, Person{age=20, name='刘琦'}, Person{age=22, name='小明'}]

        // 5.sort还有第二种用法,传递两个参数,第一个接收一个集合,第二个接收一个Comparator规则,Comparator和Comparable区别:
        // Comparable:自己(this)和别人比较,自己要实现Comparable接口并重写compareTo比较的方法
        // Comparator:找一个第三方规则进行比较
        ArrayList<Integer> lists = new ArrayList<>();
        lists.add(1);
        lists.add(4);
        lists.add(2);
        lists.add(3);

        Collections.sort(lists, new Comparator<Integer>() {
            @Override
            // 找compare接口来重写规则对元素比较:
            public int compare(Integer o1, Integer o2) {
                // return (o2 - o1); // 降序
                return (o1 - o2); // 升序
            }
        }); //[1, 2, 3, 4, 5]

        // 6.使用sort第二种方法对自定义类排序:
        ArrayList<Student> plist = new ArrayList<>();
        Student one = new Student(15, "小二");
        plist.add(one);
        Collections.addAll(plist, new Student(12, "c小三"), new Student(12, "a艾尼尔"), new Student(20, "大兄弟"));
        System.out.println(plist); // [Student{age=15, name='小二'}, Student{age=12, name='小三'}, Student{age=20, name='大兄弟'}]
        Collections.sort(plist, new Comparator<Student>(){
            @Override
            public int compare(Student o1, Student o2) {
                // 按照年龄的升序排序,年龄相同的在按姓名的第一个字符的Ascall码值升序排序:
                int result = o1.getAge() - o2.getAge();
                if (result == 0) {
                    result = o1.getName().charAt(0) - o2.getName().charAt(0);
                }
                return result;
            }
        });
        System.out.println(plist); // [Student{age=12, name='a艾尼尔'}, Student{age=12, name='c小三'}, Student{age=15, name='小二'}, Student{age=20, name='大兄弟'}]
    }
}


Map集合:

Map集合和Collection集合不是同一个体系的集合,Map集合是双链集合,而Collection是单链集合;Map集合有两个泛型,第一个泛型表示键且不重复,第二个泛型表示值,它们的关系是:将键映射到值的对象,键和值是一一对应的关系,Map集合有两个常用接口:HashMap和LinkedHashMap,相关使用如下:

// Map集合的特点:
// 1.Map集合是一个双链集合,一个元素包含两个值(key和value);
// 2.Map集合中的元素key和value中的数据类型可以相同也可以不相同。
// 3.key是不允许重复的,value是可以重复的。
// 4.key和value是一一对应的。

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

// Map集合常用接口:HashMap和LinkedHashMap
// 1.HashMap集合:底层是哈希表结构、查询的速度特别快、是一个无序的集合
// 2.LinkedHashMap: 底层是哈希表+链表、有序的(存取顺序一致)
public class MapClass {
    public static void main(String[] args) {
        // 多态的方式创建一个Map集合,两个泛型的类型可以不一致,但是存储元素是一定要对应数据类型才可以。
        Map<String,String> ml = new HashMap<>();
        // 1. put()方法:向集合中添加元素,key不能重复,否则后面的值将替换前面的值,且key不重复时返回null,key重复时返回被替换的值:
        String v1 = ml.put("name", "小明");
        System.out.println(v1); // null
        String v2 = ml.put("name", "小海");
        System.out.println(v2); // 小明
        ml.put("age", "18岁");
        System.out.println(ml); // {name=小海, age=18岁}

        // 2.remove()方法:删除指定键的值和键,返回被删除元素,如果这个键不存在,那么集合将不受影响:
        String r1 = ml.remove("age"); // 这里如果删除一个没有的元素,如果前面用基本数据类型接收就会报空指针异常,使用包装类的话就可以避免空指针异常出现
        System.out.println(r1); // 18岁
        System.out.println(ml); // {name=小海}

        // 3.get()方法:通过键获取值,key存在返回对应的value值,key不存在返回null:
        String na = ml.get("name");
        System.out.println(na); // 小海

        // 4.containsKey()方法:判断集合中是否有指定的key,返回一个布尔值:
        Boolean isExistKey = ml.containsKey("name");
        System.out.println(isExistKey); // true

        // 5.containsValue()方法:判断集合中是否有指定的value,返回布尔值:
        Boolean isExistValue = ml.containsValue("小海");
        System.out.println(isExistValue); // true

        // 6.遍历Map集合:
        Map<String, Integer> mls = new HashMap<>();
        mls.put("height", 167);
        mls.put("weight", 100);
        mls.put("age", 18);
        System.out.println(mls); // {weight=100, age=18, height=167}
        // 遍历Map集合的第一种方式:通过键找值(keySet()方法,将一个Map集合中所有key取出来放到一个Set集合中):
        // 将所有的key存到Set集合中:
        Set<String> keyArray = mls.keySet();
        // 使用迭代器遍历keyArray,并通过get()方法获取值:
        Iterator<String> its = keyArray.iterator();
        while (its.hasNext()) {
            Integer val = mls.get(its.next());
            System.out.println(val); // 100 18 167
        }

        // 第二种方式遍历Map集合:
        // Map.Entry对象: 当Map集合添加元素时,就会在Map集合中创建一个Entry对象(这里有多个Entry对象),用来记录键与值的映射关系:
        // entrySet()方法取出Map集合中的Entry对象:
        Set<Map.Entry<String,Integer>> keyList = mls.entrySet();
        // 通过增强for遍历:这里entry是变量名,Map.Entry<String,Integer>是类型
        for (Map.Entry<String,Integer> entry : keyList) {
            // 拿到key:
            String keys = entry.getKey();
            // 拿到Value:
            Integer val = entry.getValue();
            System.out.println(val); // 100 18 167
        };
    }
}


HashMap存储自定义类型键和值:

Person类:

import java.util.Objects;

public class Person {
    private String name;

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

    private int age;

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

    public Person() {
    }

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

HashMap存储自定义类型元素:

import java.util.HashMap;

// HashMap存储自定义类型键值:
// Map集合保证key是唯一的:作为key的元素,必须重写hashCode方法和equals方法,以保证key的唯一
public class CustomTypeClass {
    public static void main(String[] args) {
        // 1.HashMap存储自定义类型键值:key为String类型,Value为Person类型
        HashMap<String,Person> ps = new HashMap<>();
        ps.put("开发部", new Person("小海", 20));
        ps.put("财务部", new Person("小红", 35));
        ps.put("行政部", new Person("小何", 18));
        ps.put("行政部", new Person("小李", 19));
        System.out.println(ps); // {财务部=Person{name='小红', age=35}, 开发部=Person{name='小海', age=20}, 行政部=Person{name='小李', age=19}}

        // 遍历集合
        for (String keys : ps.keySet()) {
            Person item = ps.get(keys);
            System.out.println(item); // Person{name='小红', age=35} Person{name='小海', age=20} Person{name='小李', age=19}
        };

        // 2.HashMap存储自定义类型键值:key为Person类型(因为key是唯一的,因此需要重写hashCode和equals方法),value为String类型:
        HashMap<Person,String> pl = new HashMap<>();
        pl.put(new Person("小海",18),"开发部");
        pl.put(new Person("小海",18),"财务部");
        pl.put(new Person("小民",18),"销售部");
        System.out.println(pl); // {Person{name='小民', age=18}=销售部, Person{name='小海', age=18}=财务部} , 这里自定义类中如果没有重写hashCode和equals方法,那么将存储两个小海的key
    }
}


HashMap的子类:LinkedHashMap

LinkedHashMap继承于HashMap集合,是Map集合的哈希表和链表实现,具有可预知的迭代顺序。

import java.util.HashMap;
import java.util.LinkedHashMap;

// LinkedHashMap集合:哈希表+链表(记录元素的顺序)
public class LinkedHashMapClass {
    public static void main(String[] args) {
        HashMap<String,String> mp = new HashMap<>();
        mp.put("a", "1");
        mp.put("b", "2");
        mp.put("c", "3");
        mp.put("b", "4");
        System.out.println(mp); // {a=1, b=4, c=3} , 无序,key不允许重复

        // LinkedHashMap集合:
        LinkedHashMap<String,String> ls = new LinkedHashMap<>();
        ls.put("a", "1");
        ls.put("b", "2");
        ls.put("c", "3");
        ls.put("b", "4");
        System.out.println(ls); // {a=1, b=4, c=3} , 有序,key不允许重复
    }
}


Hashtable :

底层也是哈希表,也是双链集合 ,键和值都不允许空,单线程的,同步的,速度慢。

import java.util.Hashtable;

// Hashtable:底层是一个哈希表,是一个线程安全(单线程)的集合,速度慢。
public class HashTableClass {
    public static void main(String[] args) {
        Hashtable<String,String> hl = new Hashtable<>();
        // hl.put(null,"1"); // key或value都不能给null,否则报空指针异常
        hl.put("a","1"); // key或value都不能给null,否则报空指针异常
        System.out.println(hl);
    }
}


集合添加元素之优化方法:of

List接口、Set接口、Map接口都可以使用of静态方法,注意只是这个三个接口可以使用实现类不能使用,可以给集合一次添加多个元素,使用规则:集合的元素个数确定,才可以使用此方法,使用此方法后就不能在使用add/put等方法添加元素了。

import java.util.List;
import java.util.Map;
import java.util.Set;

// of方法是Set接口、List接口、Map接口共有的方法,它是一个静态的方法,可以给一个集合一次性添加多个元素
// 注意:of方法只适用于List、Set、Map接口,实现类不能使用此方法;此方法的返回值是一个不可变的集合,集合不能在使用add/put等方法添加元素。
public class OfMethodsClass {
    public static void main(String[] args) {
        List<String> lof =  List.of("a","b","c");
        // lof.add("d"); // 报错
        System.out.println(lof); // [a, b, c]

        Set<Integer> sof = Set.of(1,2,3);
        System.out.println(sof); // [1, 2, 3],不允许存重复元素

        Map<String,Integer> mof = Map.of("a",1,"b",2);
        System.out.println(mof); // {b=2, a=1},不允许存重复元素
    }
}

提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者删除。

笔者:苦海



版权声明:本文为weixin_46758988原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。