java Collection集合 基本用法和原理

java Collection集合 基本用法和原理,第1张

java Collection集合 基本用法和原理 二、 Collection 接口 一、接口描述
  • public interface Collectionextends Iterable
    
  • Collection 层次结构 中的根接口。Collection 表示一组对象的集合,这些对象也称为 collection 的 元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序 的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:它提供更具体的子接 口(如 Set 和 List)实现。

二、List接口 (一)、接口描述
public interface List extends Collection 
  • 是有序的 collection 。
  • 可以存放重复的元素
  • 此接口的用户可以对列表中每个元素的插入位置进行精 确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中 的元素, 不提供具体的实现方法。
  • 具体的常用实现类为 : Vector, ArrayList, linkedList
(二)、ArrayList 类用法
// 该类的继承的类 与 实现的接口
public class ArrayList extends AbstractListimplements List, RandomAccess, Cloneable, Serializable
  • ArrayList创建与使用
public static void arrayList() {
    // 创建一个List 集合
    // 这里的 表示泛型, 表示这个集合要存储的数据类型
    List list = new ArrayList<>();
    // 向集合中 添加数据
    list.add("张三");
    list.add("李四");
    list.add("王五");
    // 获取集合的内容大小
    int size = list.size();


    // 查看是否包含指定内容
    System.out.println(list.contains("张三"));

    // 删除指定数据
    list.remove("张三");
    size = list.size();
    for (int i = 0; i < size; i++) {
        // 获取集合内容
        System.out.println(list.get(i));
    }
    // 替换指定位置的数据
    list.set(1, "张三");
    size = list.size();
    for (int i = 0; i < size; i++) {
        // 获取集合内容
        System.out.println(list.get(i));
    }
    // 转换成数组
    String[] arr = list.toArray(new String[]{});
}
  • 实现原理
    • 采用的动态对象数组实现的, 默认构造方法创建了一个空数组
    • 在第一次添加数据的时候, 数组会扩充容量为10, 之后扩充的算法: 原来的数组的大小 + 原来数组的一半
  • 注意点
    • 因为是数组实现的,不适合删除以及插入
    • 为了防止数组的动态扩充过多, 建议初始化ArraysList时, 指定初始容量
    • 是线程不安全的, 建议在单线程下使用
(三)、Vector类的使用
// 该类的继承的类 与 实现的接口
public class Vector extends AbstractListimplements List, RandomAccess, Cloneable, Serializable
  • Vector创建与使用’
public static void vector() {
    // 创建Vector 集合
    List v = new Vector<>();
    // 添加数据
    v.add("张三");
    v.add("李四");
    v.add("王五");

    int size = v.size();
    for (int i = 0; i < size; i++) {
        System.out.println(v.get(i));
    }
 // 具体用法与 ArrayList 差不多   
}
  • 实现原理
    • 也是采用的动态对象数组实现的, 默认构造方法创建一个容量为10的对象数组
    • 扩充的算法: 当扩充增量为0的时候, 扩充原来的2倍, 当增量大于0的时候, 新数组大小 = 就数组大小 + 增量
  • 注意点
    • 也不适合插入和删除
    • 为了防止扩充过多, 建议指定容量
    • 是线程安全的, 适合多线程下使用, 在单线程使用效率较低
(四)、linkedList 类的使用
// 该类的继承的类 与 实现的接口
public class linkedList extends AbstractSequentialListimplements List, Deque, Cloneable, Serializable
  • linkedList创建与使用(用法都类似)
public static void linkedList() {
    // 创建
    List linkedlist = new linkedList<>();
    // 添加数据
    linkedlist.add("张三");
    linkedlist.add("李四");
    linkedlist.add("王五");

    int size = linkedlist.size();
    for (int i = 0; i < size; i++) {
        System.out.println(linkedlist.get(i));
    }
}
  • 原理
    • 使用链表实现的
  • 注意点
    • 对插入与删除 性能高,但不适合遍历
(五)、总结
  • 如果考虑到安全问题, 建议使用Vector 集合
  • 如果频繁的插入, 删除 *** 作, 建议使用linkedList 集合
  • 如果频繁的遍历, 可以使用 ArraysList
三、Set接口 (一)、接口描述
// 继承与实现
public interface Set extends Collection
  • 是一个无序的collection
  • 不允许出现重复的元素,
  • 具体的常用实现类有:HashSet、TreeSet、linkedHashSet
(二)、HashSet类用法
public class HashSet extends AbstractSet implements Set, Cloneable,Serializable
  • 创建与使用
 // 创建一个HashSet集合
Set hs = new HashSet<>();
hs.add("张三");
hs.add("李四");
hs.add("王五");
hs.add("赵六");
String[] items = hs.toArray(new String[]{});
for (String item : items) {
    System.out.println(item);
}

// 示例2
 Set hs = new HashSet<>();
Cat c1 = new Cat("小红", 3, 5);
Cat c2 = new Cat("小黑", 2, 1);
hs.add(c2);
hs.add(c1);
hs.add(new Cat("小白", 3, 2));
hs.add(new Cat("小黄", 2, 3));
hs.add(new Cat("小绿", 4, 4));

// 添加一个属性相同的数据,但内存地址不同
hs.add(new Cat("小红", 3, 5)); // 是可以插进去, 此时有两个小红
// 内存地址相同
hs.add(c2) // 只会存在一个 ‘小黑’
Cat[] items = hs.toArray(new Cat[]{});
for (Cat item : items) {
    System.out.println(item);
}

  • 实现原理

    • 于哈希表(hashMap) 实现的
      • 哈希表存储结构就是: 数组 + 链表, 数组中的每个元素都以链表的形式存储
      • 如果把对象存储到哈希表中呢?
        • 先要计算对象的hashCode 值, 根据数组的长度 取余, 来决定对象要存储数组的哪个位置
    • 添加元素时, 把元素作为HashMap的Key 存储, HashMap的value 使用一个固定的Object对象
    • 排除元素是通过HashCode来检查对象是否相同
  • 注意

    • 添加的元素不允许重复,可以使用null元素(但只能出现一个)
    • 不保证顺序持久不变
    • 判断两个对象对象是否相同, 先判断两个对象的hashCode 是否相等**(如果相等, 但是不一定是同一对象, 如果不等, 那一定不是同一对象)**,还要在通过equals判断(如果相同,则是同一对象, 反之)。
    • 自定义的对象,如果要实现属性值相同则认为同一对象, 这种需求只需要,重写hashCode 和 equals 方法即可。
(三、)TreeSet 类
public class TreeSet extends AbstractSet implements NavigableSet,Cloneable, Serializable
  • TreeSet类 创建与使用
public static void treeSet() {
    // 创建一个TreeSet 集合, 
    // 使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
    // param1: 比较器(Comparator)
    Set st = new TreeSet<>(new CatComparator());
    Cat c1 = new Cat("小红", 3, 1);
    Cat c2 = new Cat("小黑", 2, 2);
    Cat c3 = new Cat("小黄", 2, 3);
    Cat c4 = new Cat("小蓝", 2, 4);
    st.add(c1);
    st.add(c2);
    st.add(c3);
    st.add(c4);
    Cat[] cats = st.toArray(new Cat[]{});
    for (int i = 0; i < cats.length; i++) {
        System.out.println(cats[i]);
    }
}

  • 实现原理
    • 有序的, 基于TreeMap(二叉树数据结构)实现的
    • 对象需要比较大小, 通过对象比较器(Comparator/Comparable)来实现
    • 对象比较器还可以去除重复元素, 当通过比较的两个数是相同的,会认为这两个对象也是相同的, 会进行去重
(四)、linkedHashSet 类
public class linkedHashSet extends HashSet implements Set, Cloneable,Serializable
  • linkedHashSet 使用
 // 创建 linkedHashSet 集合
Set set = new linkedHashSet<>();
Cat c1 = new Cat("小红", 3, 1);
Cat c2 = new Cat("小黑", 2, 2);
Cat c3 = new Cat("小黄", 2, 3);
Cat c4 = new Cat("小蓝", 2, 4);
set.add(c1);
set.add(c2);
set.add(c3);
set.add(c4);

Cat[] cats = set.toArray(new Cat[] {});
for (int i = 0; i < cats.length; i++) {
    System.out.println(cats[i]);
}
  • 实现原理
    • 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外 在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序, 即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。
(五) 、总结
  • 有排序, 可以选择 TreeSet
  • 无排序, 也不用保证顺序 可以选择 HashSet
  • 无排序,也不用保证顺序, 可以选择 linkedHashset

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5660452.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存