学习笔记17.集合框架

集合框架

集合概念

一:概念

对象的容器,实现了对对象常用的操作,类似数组的功能。

二:集合和数组的区别

  1. 数组长度固定,集合长度不固定。
  2. 数组可以存储基本类型和引用类型,集合只能存储引用类型。

位置:java.util.*

Collection体系集合

Collection体系

Collection父接口

特点:代表一组任意类型的对象,无序、无下标、不能重复。

常用方法:

  • boolean add(Object obj) //添加一个对象。
  • boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中。
  • void clear() //清空此集合中的所有对象。
  • boolean contains(Object o) //检查此集合中是否包含o对象。
  • boolean equals(Object o) //比较此集合是否与指定对象相等。
  • boolean isEmpty() //判断此集合是否为空。
  • boolean remove(Object o) //在此集合中移除o对象
  • int size() //返回此集合中的元素个数。
  • Object[] toArray() //将此集合转换成数组。

迭代器:

创建迭代器:

Iterator it = collection.iterator();

方法:

  • hasNext();判断有没有下一个元素。
  • next();获取下一个元素。
  • remove();删除当前元素。

注意:迭代过程中不能使用collection删除方法。

List接口

特点:有序、有下标、元素可以重复。

方法:

  • void add(int index,Object 0) //在index位置插入对象o。
  • boolean addAll(int index,Collection c) //将一个集合中的所有元素添加到此集合中的index位置。
  • Object get(int index) //返回集合中指定位置的元素。
  • List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素(含头不含尾)。
  • int indexOf(Object o)返回对象o在集合中第一次出现的脚标。

迭代器:

ListIterator可以向前或向后遍历,添加、删除、修改元素。

创建迭代器:

ListIterator lit = list.listIterator();

注意:

  1. 集合中删除数字元素时要注意remove方法中要传入Object类型或Integer类型,如果直接传入int类型,则会判定为角标。

List实现类

ArrayList【重点】:

  • 数组结构实现,查询快、增删慢;
  • JDK1.2版本,运行效率快,线程不安全。

源码分析:

  1. DEFAULT_CAPACITY = 10; 默认容量

    ​ 注意:如果没有向集合中添加任何元素时,容量为0,添加一个任意元素之后,容量为10。

    ​ 每次扩容扩容为原来的1.5倍。

  2. elementDate 用来存放元素的数组。

  3. size 实际的元素个数。

  4. add() 添加元素。

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

Vector:

  • 数组结构实现,查询快、增删慢;
  • JDK1.0版本,运行效率慢、线程安全。

枚举器:

创建枚举器:

Enumeration en = vector.elements();

方法:

  1. hasMoreElements() 判断是否有下一个元素。
  2. nextElement() 取出下一个元素。
  3. firstElement、lastElement、elementAt();

LinkedList:

  • 链表结构实现,增删快,查询慢。

源码分析:

int size:集合的大小。

Node first;链表的头节点

Node last;链表的尾节点

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

ArrayList和LinkedList区别

区别

泛型

泛型概述:

Java泛型时JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。

常见形式有泛型类、泛型接口、泛型方法。

语法:

  • <T,...> T称为类型占位符,表示一种引用类型。

好处:

  1. 提高代码的重用性。
  2. 防止类型转换异常,提高代码安全性。

泛型类:

语法:类名<T>,T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开。

注意:

  1. 泛型只能使用引用类型
  2. 不同泛型类型对象之间不能互相赋值。
  3. 泛型类中不能使用T创建对象。

泛型接口

语法:接口名<T>,T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开。

注意:不能创建泛型静态常量。

泛型方法

语法:<T> 返回值类型

注意:T的类型会自动变为方法参数传入值的类型。

泛型集合:

概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。

特点:

  • 编译时即可检查,而非运行时抛出异常。
  • 访问时,不必类型转换(拆箱)。
  • 不同泛型之间引用不能互相赋值,泛型不存在多态。

Set子接口

特点:无序、无下标、元素不可重复。

方法:全部继承自Collection中的方法。

Set实现类

HashSet【重点】:

存储结构:哈希表(数组+链表+红黑树)

特点:

  • 基于HashCode计算元素存放位置。
  • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

存储过程:

  1. 根据hashcode,计算保存的位置。如果此位置为空,则直接保存,如果不为空,执行第二部。
  2. 再执行equals方法,如果equals方法为true,则认为时重复元素,否则,形成链表。

TreeSet

存储结构:红黑树

要求:元素必须要实现Comparable接口,compareTo()的返回值为0,认为是重复元素。

Comparator接口:实现定制比较(比较器)

小案例:

//要求:使用TreeSet集合实现字符串按照长度进行排序。
public static void main(String[] args) {
    //创建集合,并指定比较规则
    TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            int n1 = o1.length()-o2.length();
            int n2 = o1.compareTo(o2);
            return n1==0?n2:n1;
        }
    });
    //添加数据
    treeSet.add("helloWorld");
    treeSet.add("pingguo");
    treeSet.add("zhangsan");
    treeSet.add("beijing");
    treeSet.add("cat");
    treeSet.add("nanjing");
    treeSet.add("xian");
    //输出
    System.out.println(treeSet.toString());

Map体系集合

Map体系

Map父接口

特点:存储键值对(Key-Value),无序,无下标,键不可重复,值可重复。

方法:

  • V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
  • Object get(Object key) //根据键值获取对应的值。
  • keySet() //返回此地图中包含的键的Set视图。
  • Collection<V> values() //返回包含所有值的Collection集合。
  • entrySet //返回此地图中包含的映射的Set视图。

HashMap【重点】:

JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。

存储结构:哈希表(数组+链表+红黑树),使用key的hashcode和equals作为重复。

源码分析:

属性:
1. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // hashMap初始容量大小
2. static final int MAXIMUM_CAPACITY = 1 << 30; //hashMAp的数组最大容量
3. static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认加载因子,每次扩容长度为原来的2倍。
4. static final int TREEIFY_THRESHOLD = 8; //jdk1.8当链表长度大于8,会把链表替换为红黑树。
5. static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8当链表长度小于6,把红黑树替换为链表。
6. static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8当链表长度大于8,数组长度大于等于64,调整为红黑树
7. transient Node<K,V>[] table;//哈希表中的数组
8. size;//元素个数
无参构造:
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

刚创建hashMap之后没有添加元素 table=null size=0 目的:节省空间

put方法
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

总结:

  1. HashMap刚创建时table时null,为了节省空间。当添加第一个元素时,table容量调整为16。
  2. 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容大小为原来的两倍。目的是减少调整元素的个数。
  3. jdk1.8 当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的是提高执行效率。
  4. jdk1.8 当链表长度小于6时,调整为链表。
  5. jdk1.8以前,链表从头插入,jdk1.8以后是从尾插入。

TreeMap

实现了SortedMap接口,可以对key自动排序。

存储结构:红黑树

要求:元素必须要实现Comparable接口,compareTo()的返回值为0,认为是重复元素。

Comparator接口:实现定制比较(比较器)

Colletions工具类

概念:集合工具类,定义了除了存取以外的集合常用方法。

方法:

  • reverse()//反转集合
  • shuffle()//随机重置集合元素顺序
  • sort() //升序排序(元素必须实现Comparable接口)
  • copy() // 复制集合(两个集合大小必须一致)

总结

总结

posted @ 2021-03-09 18:59  Starumi  阅读(88)  评论(0)    收藏  举报