前言
自我感觉在Java中提及到集合就需要想到存储,想到存储就需要想到数组以及集合,这是非常好用的两个框架,好吧,其实我暂时没想起来还有其他的存储方式
这里先把集合的架构图贴出来,先看架构图,看不懂没关系,慢慢学习,学完再来看,可能还是看不懂,在实际开发过程中慢慢去使用就懂了,这是一个过程,当然,现在我也不懂,边写边学习,算是笔记。
好吧,看似很复杂,其实确实很复杂,我也看不太懂,简单说一下我懂得
collection map 这两个是同级的关系 ,并不是collection里面有map ,这也是我自己的理解
这个图就很明显,单列双列的很清晰明了,作为初级没必要学的那么牛掰,懂怎么用就行,知道一下基础的API就可以
在这里声明一下,子类继承了父类,那么就可以使用父类中的方法
collection 接口
这里先说一下collection接口 collection接口作为集合的顶级接口,有三个子接口
使用ALT+7 快捷键就可以打开查看,这是controller接口中的所有的方法。基本上所有的都是见名知意,
/**
* Returns the number of elements in this collection. If this collection
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this collection
*/
int size(); //获取长度
boolean isEmpty(); //是否为空
boolean contains(Object o); //是否包含传入的元素
Iterator<E> iterator(); //获取迭代器的
Object[] toArray(); //转类型的
boolean add(E e); //添加的
boolean remove(Object o); //删除的
boolean containsAll(Collection<?> c); //包含所有的
这里就写这些,不过多写,主要用不着,看了也没用,用的时候idea点开看看注释用就行
List
继承collection
int size(); //返回值: 该列表中的元素数
boolean isEmpty(); // 返回值: 如果此列表不包含任何元素,则为true 判断是否为空的
boolean contains(Object o);// 如果此列表包含指定的元素,则为true 判断一下有没有你给的元素在集合里面
Iterator<E> iterator(); //序列化的
Object[] toArray(); //返回一个数组,该数组按正确的顺序(从第一个元素到最后一个元素)包含此列表中的所有元素
boolean add(E e); //添加的 将指定的元素追加到此列表的末尾(可选操作)
boolean remove(Object o); //删除的
boolean containsAll(Collection<?> c); //添加所有
boolean addAll(Collection<? extends E> c); //添加所有 将指定集合中的所有元素追加到此列表的末尾
boolean addAll(int index, Collection<? extends E> c); //添加所有 将指定集合中的所有元素插入此列表中指定的位置(可选操作)
//这里参数不一样 根据实际情况给定参数
boolean removeAll(Collection<?> c); //删除的 从此列表中删除指定集合中包含的所有元素(可选操作)
boolean retainAll(Collection<?> c); //仅保留此列表中包含在指定集合中的元素(可选操作)。换句话说,从该列表中删除指定集合中未包含的所有元素。
//根据指定的Comparator引发的顺序对此列表进行排序 排序的
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
void clear(); //从该列表中删除所有元素(可选操作)。此调用返回后,列表将为空。 删除所有
//将指定的对象与此列表进行相等性比较。当且仅当指定的对象也是一个列表,两个列表的大小相同,并且两个列表中所有对应的元素对都相等时,返回true。判断是否存在的
boolean equals(Object o);
int hashCode(); //返回此列表的哈希代码值。列表的哈希代码被定义为以下计算的结果
E get(int index); //返回此列表中指定位置的元素。索引从0开始
E set(int index, E element); //用指定的元素替换此列表中指定位置的元素(可选操作)。
void add(int index, E element); //在此列表中的指定位置插入指定的元素(可选操作)
E remove(int index);//删除此列表中指定位置的元素(可选操作)。将任何后续元素向左移动(从其索引中减去一)。返回从列表中删除的元素。
int indexOf(Object o); 返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回-1。 这个时返回第一个
int lastIndexOf(Object o); 返回此列表中指定元素最后一次出现的索引 这是最后一个
ListIterator<E> listIterator(); //返回此列表中元素的列表迭代器
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
}
这里看一下官方的注解我翻译过来了
有序集合(也称为序列)。该界面的用户可以精确控制每个元素在列表中的插入位置。用户可以通过元素的整数索引(在列表中的位置)访问元素,并在列表中搜索元素。
ArrayList
LinkedList
Vector
Stack
看不懂了难死了
Iterator接口和ListIterator接口
看不懂了难得
Set
继承collection
这里注意,list有序的,set无序的
不包含重复元素的集合。更正式地说,集合不包含一对元素e1和e2,因此e1.equals(e2),最多包含一个null元素。正如其名称所暗示的那样,该接口对数学集抽象进行建模。
Set接口在所有构造函数的约定以及add、equals和hashCode方法的约定上放置了从Collection接口继承的其他约定。为了方便起见,这里还包含了其他继承方法的声明。(这些声明附带的规范已针对Set接口进行了定制,但不包含任何附加规定。)
对构造函数的额外规定是,所有构造函数都必须创建一个不包含重复元素的集合(如上所述),这一点并不奇怪。
注意:如果可变对象用作集合元素,则必须非常小心。如果对象的值在mann中发生更改,则不指定集合的行为
也就是说,list中的内容可重复,更具索引去拿即可,但是set不可以,是无序的,第二次添加的内容会直接返回false
这里也不仔细去看具体的方法,idea点进去都一样的,注释写的很清楚
HashSet类
HashSet类
TreeSet类
EnumSet类
各Set实现类的性能分析
Queue
在此之前我都没见过这玩意
Queue(队列)是一种经常用于存储和管理数据的数据结构。它遵循先进先出(FIFO)的原则,也就是说最先插入的元素将最先被取出。
队列通常具有两个主要操作:
- 入队(enqueue):将元素添加到队列的末尾。
- 出队(dequeue):从队列的前端移除并返回元素
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。 所以这玩意不知道也行。
我自己简单总结就是,先进去的先出来,而且还有限制,插入的操作只会在后面去插入,不能去指定某个位置去插入
Map集合
map集合就是KEY-VALUE 这样的一个KEY对应一个value 但是key 以及 value 的类型是可以自己定义的,比如说 key 是String value 是集合
这是map接口里面的方法
HashMap与Hashtable
HashMap与Hashtable是Map接口的两个典型实现,它们之间的关系完全类似于ArrayList与Vertor。HashTable是一个古老的Map实现类,它提供的方法比较繁琐,目前基本不用了,HashMap与Hashtable主要存在以下两个典型区别:
♦ HashMap是线程不安全,HashTable是线程安全的。
♦ HashMap可以使用null值最为key或value;Hashtable不允许使用null值作为key和value,如果把null放进HashTable中,将会发生空指针异常。
为了成功的在HashMap和Hashtable中存储和获取对象,用作key的对象必须实现hashCode()方法和equals()方法。
HashMap工作原理如下:
HashMap基于hashing原理,通过put()和get()方法存储和获取对象。当我们将键值对传递给put()方法时,它调用建对象的hashCode()方法来计算hashCode值,然后找到bucket位置来储存值对象。当获取对象时,通过建对象的equals()方法找到正确的键值对,然后返回对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链表的下一个节点中。
hashMap
它继承MAP 实现了AbstractMap<K,V> map接口里面是有这个
慢慢看,反正我还没看懂
hashTable
LinkedHashMap
LinkedHashMap使用双向链表来维护key-value对的次序(其实只需要考虑key的次序即可),该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。
Properties
Properties类时Hashtable类的子类,它相当于一个key、value都是String类型的Map,主要用于读取配置文件。
TreeMap
TreeMap是SortedMap的实现类,是一个红黑树的数据结构,每个key-value对作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap也有两种排序方式:
♦ 自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则会抛出ClassCastException。
♦ 定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。
各Map实现类的性能分析
♦ HashMap通常比Hashtable(古老的线程安全的集合)要快
♦ TreeMap通常比HashMap、Hashtable要慢,因为TreeMap底层采用红黑树来管理key-value。
♦ LinkedHashMap比HashMap慢一点,因为它需要维护链表来爆出key-value的插入顺序。
好了,太难了,我再去看看把