【JavaSE】之集合框架(下)

简介: 【JavaSE】之集合框架(下)

四、Set


1.TreeSet


定义:


可排序的集合;

不能存储空对象;

底层是红黑树;

使用TreeSet 存储对象必须要使用自然排序或者比较器


自然排序


要存储的对象 必须实现了 Comparable 接口,并重写了 compareTo()

在 compareTo() 方法中 制定了比较规则

存储的对象 通过 与 之前的节点对比,返回正数则在 节点的右子树;负数则存储在左子数;返回 0 不存储对象(重复了)

// 实体类实现接口
public class Person implements Comparable<Person> {
    private int id;
    private String name;
    private int age;
    /**
     * 重写CompereTo 接口
     *      要求:  id 从大到小
     *             id相同,age从小到大
     * @param o
     * @return
     */
    @Override
    public int compareTo(Person o) {
        if (this.id == o.getId()){
            return this.age-o.getAge() ;
        }
        return o.getId() - this.id ;
    }
}
// 测试
public class Demo02 {
    public static void main(String[] args) {
        TreeSet<Person> people = new TreeSet<>();
        people.add(new Person(1,"ls",44));
        people.add(new Person(1,"zs",12));
        people.add(new Person(8,"t7",14));
        people.add(new Person(7,"t7",14));
        people.forEach(item -> System.out.println(item));
    }
}

比较器


在创建TreeSet集合的时候,通过构造方法传递实现了Comparator接口的实现类对象

实现类对象要重写了compare()方法,在方法里面制定排序规则

// 比较器
public class MyCompartor implements Comparator<Person> {
    /**
     * id从小到大
     * id相同,age从大到小
     * @param o1 存储的对象
     * @param o2 上一个节点的对象
     * @return
     */
    @Override               // 11         88
    public int compare(Person o1, Person o2) {
        if (o1.getId() != o2.getId())
            return o1.getId()-o2.getId();
        return o2.getAge()-o1.getAge();
    }
}
// 测试
public class Demo03 {
    public static void main(String[] args) {
        // 通过构造方法传入 比较器
/*
        TreeSet<Person> people = new TreeSet<>(new MyCompartor());
        people.add(new Person(1,"ls",44));
        people.add(new Person(1,"zs",12));
        people.add(new Person(8,"t7",14));
        people.add(new Person(7,"t7",14));
        people.forEach(item -> System.out.println(item));
*/
        // 匿名内部类
        TreeSet<Person> people = new TreeSet<>(new Comparator<Person>(){
            @Override
            public int compare(Person o1, Person o2) {
                if (o1.getId() != o2.getId())
                    return o1.getId()-o2.getId();
                return o2.getAge()-o1.getAge();
            }
        });
        people.add(new Person(1,"ls",44));
        people.add(new Person(1,"zs",12));
        people.add(new Person(8,"t7",14));
        people.add(new Person(7,"t7",14));
        people.forEach(item -> System.out.println(item));
    }
}

自然排序 VS 比较器


比较器的优先级别高于自然排序

自然排序需要存储的对象类结构发生改变(实现了 Comparable 接口,并重写compereTo方法)

自然排序的可读性更高,并且排序规则不可见

比较器会创建多一个类


2.HashSet


什么是有序和无序?


  • 有序: 根据添加的顺序先后,遍历时以同样的顺序输出
  • 无序: 遍历输出 与 添加时的顺序无关(HashSet是无序的)


版本:


JDK1.7 : 底层 hash表(不可变) + 链表

JDK1.8 : 底层 hash表(动态数组) + 链表 + 红黑树


重点:


存储的对象通过hashCode()得到hash值,根据hash值找到在hash表中对应的位置

再根据equals() 判断是否内容相等,内容相等则不存储

当hash表中的对象超过容量的负载因子数时,进行数组扩容,容量为原来的2倍

当一个链表中的对象超过8个,则会转换为红黑树

public class Demo02 {
    public static void main(String[] args) {
        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(12);
        hashSet.add(11);
        hashSet.add(22);
        hashSet.add(22);
        // lambda表达式 ,打印结果
        hashSet.forEach(item -> System.out.println(item));
        // 输出:22 11 12 ,说明HashSet是无序的
    }
}


五、Map


1.HashMap


特点:


无序,key不可重复

简单使用:

key,value都可以为null, key为null的时候存储在HashMap的第一个位置

当key相同时,新的value会覆盖旧的value

public class Demo01 {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        // 1、添加
        map.put("a",13);
        map.put("b",12);
        map.put("c",11);
        map.put("d",678);
        map.put("a",99);  // key重复,后面添加的会覆盖前面的
        System.out.println(map); //{a=99, b=12, c=11, d=678}
        // 2、删除
        // 根据key删除
        map.remove("a");
        // 根据key value 删除
        map.remove("c",11);
        // 3、修改
        // 根据key 修改value
        map.replace("b",88);
        // 4、打印
        System.out.println(map); //{b=88, d=678}
        // 5、遍历 for不可用
        System.out.println("----------- 使用keyset方法转换为保存key值的set集合 ------------");
        // 将 map 中的key值存储到 set集合中,set能调用的遍历方法他也能
        Set<String> set1 = map.keySet();
        Iterator<String> iterator1 = set1.iterator();
        while (iterator1.hasNext()){
            String key = iterator1.next();
            System.out.println("key:"+key +",value:"+map.get(key));
        }
        System.out.println("----------- 使用entrySet方法转换为保存key,value 的Set集合 ------------");
        // 将key,value 保存再Map类的内部类 Entry 类中
        Set<Map.Entry<String, Integer>> set2 = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator2 = set2.iterator();
        while (iterator2.hasNext()){
            Map.Entry<String, Integer> entry = iterator2.next();
            System.out.println("key:"+entry.getKey() + ",value:"+entry.getValue());
        }
    }
}


2.TreeMap


特点:


底层是红黑树 ,无序 key不可重复

简单使用:

存储映射的关系过程中,需要key使用 自然排序或传递比较器(比较器根据key进行排序)

key不能为null ,value可以为null

添加相同 key 时,新的value会覆盖旧的value(底层:自然排序的compareTo() 或比较器compare()

方法返回值为0,调用t.setValue(value),实现新的值覆盖旧的值)


public class Demo02 {
    public static void main(String[] args) {
        System.out.println("--------------TreeMap-----------------");
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("a",1);
        treeMap.put("a",2);
        // treeMap.put(null,1);
        treeMap.put("b",null);
        System.out.println(treeMap);
        //{a=2, b=null}
        System.out.println("--------------HashMap-----------------");
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("a",11);
        hashMap.put(null,11);
        hashMap.put("b",null);
        System.out.println(hashMap);
        //{null=11, a=11, b=null}
    }
}

3.HashTabl


特点:


  • 无序,key不可重复


简单使用:


  • key,value都不能为空
public class Demo03 {
    public static void main(String[] args) {
        Hashtable<String, Integer> hashtable = new Hashtable<>();
        hashtable.put("a",1);
        hashtable.put("c",2);
        //hashtable.put(null,2);    NullPointerException
        //hashtable.put("d",null);  NullPointerException
        System.out.println(hashtable);
    }
}

六.集合工具类Collections


Java提供了一个操作Set、List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象实现同步控制等方法。


排序操作:排序相关的、顺序相关的功能


reverse():反转指定列表中元素的顺序

shuffle():使用默认随机源对指定列表进行置换(每一次的顺序都不一样)或者打乱顺序 :打乱集合顺序

sort():根据指定比较器产生的顺序对指定列表进行排序(默认从小到大)或者在指定列表的指定位置处交换元素。注意:sort(list)有使用前提:被排序的集合元素必须实现了Comparable接口,重写接口中的compareTo方法定义排序的规则;

swap():交换一下顺序 rotate():根据指定的距离轮换指定列表中的元素


查找和替换操作


max():根据元素的自然顺序,返回给定 collection 的最大元素

min():根据元素的自然顺序,返回给定 collection 的最小元素

replaceAll():使用另一个值替换列表中出现的所有某一指定值 frequency()返回指定 collection中等于指定对象的元素数

binarySearch():使用二分搜索法搜索指定列表,以获得指定对象。

indexOfSubList():查找子列表在列表中第一次出现的位置,没有返回-1

lastIndexOfSubList():查找子列表在列表中最后一次出现的位置,没有返回-1

fill():使用指定元素替换指定列表中的所有元素


同步控制


Collections类中提供了多个synchronized…()方法,这些方法可以将指定集合包装成线程同步(线程安全)的集合,从而可以解决多线程并发访问集合时的线程安全问题。

Java中常用的集合框架中的实现类 ArrayList、Linkedlist、 HashSet、TreeSet、HashMap和TreeMap 都是线程不安全的。如果有多个线程访问它们,而且有超过一个的线程试图修改它们,则存在线程安全的问题。

Collections提供了多个类方法可以把它们包装成线程同步的集合。


代码示例:

public class CollectionsTest {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(9);
        list1.add(2);
        list1.add(2);
        Integer[] arr = {7,6,9};
// addAll(Collection<? super T> c, T... elements) 将所有指定的元素添加到指定的集合。
        Collections.addAll(list1,4,5,6);
        Collections.addAll(list1,arr);
        // 打印集合
        System.out.println(list1);//[9, 2, 2, 4, 5, 6, 7, 6, 9]
        // 对集合元素进行排序
        Collections.sort(list1);
        System.out.println(list1);//[2, 2, 4, 5, 6, 6, 7, 9, 9]
    }
}


后记


Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~

相关文章
|
6月前
|
存储 算法 Java
JAVA的集合框架
JAVA的集合框架
31 0
|
6月前
|
存储 Java 容器
Java中的集合框架
Java中的集合框架
46 0
|
6月前
|
存储 Java 开发者
Java集合框架:Java中的集合框架有哪些?
Java集合框架:Java中的集合框架有哪些?
52 0
|
4月前
|
存储 安全 Java
Java的集合框架
Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
28 1
|
6月前
|
存储 算法 Java
Java 集合框架
5月更文挑战第10天
|
6月前
|
存储 安全 算法
JavaSE&集合框架
JavaSE&集合框架
33 1
|
6月前
|
存储 安全 Java
Java中的集合框架:深入理解与应用
【2月更文挑战第26天】 在Java编程中,集合框架是日常开发不可或缺的部分。它提供了一组性能优良的接口和类,用于存储和操作对象组。本文将详细解析Java集合框架的核心组件,包括其层次结构、主要接口及实现类,并探讨如何在不同场景下高效地使用它们。通过具体示例,我们将揭示集合操作的最佳实践,以及如何避免常见的陷阱和错误。
116 5
|
6月前
|
存储 算法 安全
Java中的集合框架及其应用
Java中的集合框架及其应用
|
存储 算法 搜索推荐
java——集合框架
java——集合框架
|
6月前
|
Java
java常见的集合类
java常见的集合类