集合体系及基础知识点汇总

 

********集合********

Collection:单列集合顶层接口

add() remove() clear()

集合-->数组   迭代器 iterator()  Iterator hasNext() next()

|--List:有序,有索引,可以存入重复的元素

list.size()  list.get()

|--ArrayList:底层数组结构,增删较慢,查找相对较大

|--LinkedList:底层是链表,使用物理的不相邻表示逻辑的相邻,节点:本身元素,下一个元素的地址。

增删较快,查找较慢

特点方法:操作头和尾的节点的操作

addFirst() addLast() removeFirst() removeLast() getFirst() getLast()

|--Vector:被ArrayList取代了,addElement() removeElement()

elements 枚举器   hasMoreElement nextElement

|--Set:无序,不能存储相同的元素

|--HashSet:哈希表,如何元素唯一呢, hasCode()  equals() 存储的顺序和取出的顺序可能不一致。

|--LinkedHashSet:既想保证元素唯一,又想有序。

|--TreeSet:二叉树,既可以保证元素唯一,同时还可以进行排序。

第一种方式:让元素本身具有比较性  自定义类实现Comparable 重写compareTo()方法

正整数、零、负整数

第二种方式:使集合在创建 的时候就有比较性。比较器:自定义类实现Comparator,重写compare()方法

正整数、零、负整数

当两种方式同时存在,使用集合本身的比较性,元素的比较性就会失效。

Map:双列集合的顶层接口

put(K,V)  get(k)

两种遍历方式:

keySet()--->Set<Key>   遍历Set集合,过程中通过get() 获取相应的值

entrySet()-->Set<Map.Entry> 遍历set集合,过程中通getKey() getValue()获取相应的键和值

|--HashMap

|--LinkedHashMap:既保证唯一,又有序。

|--TreeMap

|--Hashtable:被HashMap替代。区别。

泛型:不确定的类型。

|--泛型类

  1. 集合的体系

 

  1. 集合的分类

 ①单列集合:每个元素都是一个单独的个体,只有value值

 ②双列集合:每次操作都是针对一对数据,一个数据作为一个单位,key-value

 单列集合体系

Collection:所有单列集合的顶层接口

|-------List:有序的子接口

      |-------ArrayList:数组,顺序存储

      |-------LinkedList:链表,链式存储

      |-------Vector:被ArrayList取代

|-------Set:无序的子接口

      |-------HashSet:哈希存储

      |-------TreeSet:二叉树存储(会排序)

双列集合体系

Map:所有单列集合的顶层接口

    |-------HashMap:哈希存储

    |-------TreeMap:二叉树存储

1、集合和数组的区别

数组和集合类都是容器。

数组长度是固定的,集合长度是可变的。(存储数量不同)

数组中可以存储基本数据类型,集合只能存储对象。数组中存储数据类型是单一的,集合中可以存储任意类型的对象。(存储内容不同)

数组中只有Object中的方法和Length属性。集合中有很多很多方法。(方法不同)

集合类的特点,用于存储对象,长度是可变的,可以存储不同类型的对象。

********Collection********

Collection是单列集合的顶层接口,接口不能创建对象,可以创建一个具体的实现类,例如:Collection c = new ArrayList();

1、Collection接口所定义的方法:

int size();//返回此集合中元素的个数

boolean isEmpty();//判断此集合是否为空,若为空,则返回true

void clear();//清空集合

boolean contains(Object element);//判断集合是否包含某个元素

boolean add(Object element);//向集合中添加元素

boolean remove(Object element);//删除集合中的某个元素,若删除成功则返回true

Iterator iterator();//返回此集合中的元素的迭代器

boolean containsAll(Collelction c);//如果此集合包含指定集合中的所有元素,则返回true。

boolean addAll(Collelction c);//将指定集合中的所有元素添加到此集合

boolean removeAll(Collelction c);//删除两集合的交集

boolean retainAll(Collection c);//仅保留两集合的交集

Object[] toArray//返回一个包含此集合中所有元素的数组

2、Collection遍历

  ①把集合转换为数组,对数组进行遍历

Object[]  toArray();

单列集合通用的第一种遍历方式(调用toArray()方法,转为数组,然后遍历)

注意单列集合的这个toArray()方法返回值是一个Object类型的数组

多态(父类的引用指向子类的对象)中的成员方法的访问特点

1.编译看左边,运行看右边

2.编译的时候,要看父类中是否存在该方法,如果存在,编译通过,否则编译报错。

3.运行的时候,要运行子类的重写的方法,如果没有重写的方法,执行父类的方法。*/

Student stu = (Student)obj;

/*不强转为子类对象的引用stu时,obj只能调用两者共有的方法中的子类对象的方法而不能调用Student类中特有的方法.

  ②获取集合的迭代器

   Itreator 该接口是集合的迭代器接口类,定义了常见的迭代方法

Iterator迭代器是个接口,不能直接创建对象,但可以通过集合调用iterator()方法创建对象

1:boolean hasNext()

  判断集合中是否有元素,如果有元素可以迭代,就返回true。

2: E next()  

返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException

3: void remove()

从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。

  1. 迭代器的注意事项:

  1、迭代器对象虽然多次调用next方法,都是同样的方法名称,但是每次调用返回的结果是不同的,会因为next方法既可以获取下一个元素,也会让迭代器对象,向前移动一步。

  2、如果没有下一个元素,仍然调用next方法,出现NoSuchElementException(没有当前元素异常),可以使用hasNext方法判断是否有下一个元素,决定是否调用next方法

  3、hasNext方法,判断是否有下一个元素,不会移动迭代器的位置

  4、next方法,不仅可以获取下一个元素,还会移动迭代器位置

  5、不要只判断一次hasNext,就调用多次next方法

  ③高级for循环底层实现的就是迭代器

     只要实现了Iterable接口的集合,就可以使用增强型for循环进行遍历。

 

 

 

********List********

List接口是Collection的子接口,实现List接口的容器类中的元素是有顺序的,而且可以重复

List容器中的元素都对应一个整数型的序号记录其在容器中的位置,可以根据此序号存取元素。

1、List中特有的方法(带索引)

Object get(int index);//获取指定索引的元素

Object set(int index,Object element);//替换指定索引的元素,返回的是被替换掉的元素

void add(int index,Object element);//在指定的位置插入元素

Object remove(int index);//删除对于索引的元素,若不写索引,比如字符串类型,删除的是从头开始第一个出现的元素,后面有重复的也不删除

int indexOf(Object o);//集合中从前开始第一个出现o元素的索引

int lastIndexOf(Object o);//集合中从后开始第一个出现o元素的索引

2、List集合中的特有的遍历

size():获取元素的个数

get():获取指定位置的元素

 

 

********并发修改异常********

java.util.ConcurrentModificationException

原因:在迭代器(或者是在增强for循环中)操作数据时,集合本身也在操作(add,remove,clear等修改)数据,导致并发修改异常。

解决方法:要么集合本身在操作集合,要么迭代器在操作集合。

迭代器在操作集合时功能只有remove(),功能非常有限。所以引入ListInterator

ListIterator:

void

add(E e) 

将指定的元素插入列表(可选操作)。

boolean

hasNext() 

返回 true如果遍历正向列表,列表迭代器有多个元素。

boolean

hasPrevious() 

返回 true如果遍历反向列表,列表迭代器有多个元素。

E

next() 

返回列表中的下一个元素,并且前进光标位置。

int

nextIndex() 

返回随后调用 next()返回的元素的索引。

E

previous() 

返回列表中的上一个元素,并向后移动光标位置。

int

previousIndex() 

返回由后续调用 previous()返回的元素的索引。

void

remove() 

从列表中删除由 next()previous()返回的最后一个元素(可选操作)。

void

set(E e) 

指定的元素替换由 next()previous()返回的最后一个元素(可选操作)。

 

 

********List-->Vector********

List的实现类,不常用,在jdk1.0出现,在jdk1.2被ArrayList替代

特点:效率较低,线程安全(多线程),顺序存储,增删较慢

特有的方法

 void addElement(E obj)  在集合末尾添加元素

 E elementAt( int index) 返回指定角标的元素

 Enumeration elements()  返回集合中的所有元素,封装到Enumeration对象中

 Enumeration 接口(枚举器):

 boolean  hasMoreElements()

          测试此枚举是否包含更多的元素。

E nextElement()

如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

 

 

********List-->ArrayList********

底层采用数组实现,默认10。每次增长60%,((oldCapacity * 3)/2 + 1) 查询快,增删慢。

实现原理:数组实现,顺序存储,通过物理内存的位置关系,来表达描述逻辑的顺序相邻。 

查找快, 增删慢。

 

  1. 数组为什么是查询快增删慢?

因为数组的内存空间地址是连续的.

ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。

当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。

由于ArrayList是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素,所以慢。数组是可以直接按索引查找, 所以查找时较快。

可以考虑,假设向数组的0角标位置添加元素,那么原来的角标位置的元素需要整体往后移,并且数组可能还要增容,一旦增容,就需要将老数组的内容拷贝到新数组中。所以数组的增删的效率是很低的。

 

 

********List-->LinkedList********

链表(节点)实现,链式存储,不通过连续的物理内存位置的相邻,来表示逻辑顺序的相邻 

增删快, 查找慢

特有方法:

addFirst(E e) 在该列表开头插入指定的元素。

addLast(E e) 将指定的元素追加到此列表的末尾。

getFirst() 返回此列表中的第一个元素。

getLast() 返回此列表中的最后一个元素。

removeFirst() 从此列表中删除并返回第一个元素。

removeLast() 从此列表中删除并返回最后一个元素。

如果集合中没有元素,获取或者删除元

会抛出异常:NoSuchElementException

 

 

1、为什么链表的增删快,而查询慢?

由于LinkedList:在内存中的地址不连续,需要让上一个元素记住下一个元素。所以每个元素中保存的有下一个元素的位置。虽然也有角标,但是查找的时候,需要从头往下找,显然是没有数组查找快的。但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,让新元素记住下一个元素就可以了,所以插入很快。

由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素。这样的增删效率较高。

但查询时需要一个一个的遍历, 所以效率较低。

  1. ArrayList与LinkedList的区别?**************

他们都是线性表,但是ArrayList基于数组(顺序存储),LinkedList基于链表(链式存储)

由于实现的不同,ArrayList在随机访问元素时性能较高,插入和删除元素时效率较低,LinkedList则反之。

 

********Set********

Set:注重独一无二的性质,该体系集合可以知道某物是否已经存在于集合中,不会存储重复的元素。用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。

该集合中没有特有的方法,直接继承自Collection。

Set集合的特点:无序、数据不重复。

主要包含的实现类有:HashSet、TreeSet、LinkedHashSet ...

 

********Set-->HashSet********

HashSet的底层结构是HashMap

  1. HashSet如何检查重复确保元素唯一呢?

元素的哈希值是通过元素的hashcode方法来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法。如果 equls结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。

  1. 哈希值相同,equals为false的元素是怎么存储呢?

就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。

******HashSet-->LinkedHashSet******

是HashSet的一个子类。

和HashSet的不同之处在于,具有可预知的迭代顺序,存储的顺序和遍历集合时取出的顺序一致。

 

********Set-->TreeSet********

TreeSet是一个可排序集合,基于红黑树(自平衡二叉树),默认按元素的自然顺序升序排列。

1、也是一个Set子类,也可以保证元素的唯一,底层结构是二叉树。

2、既可以保证元素唯一,也可能进行自动排序

当存入的是基本数据类型和字符串时,TreeSet有自动升序排列的能力。而当存入的是自定义引用类型,遍历时会抛出异常。因为TreeSet并不知道如何排序。

两种比较器:

(1)Comparable接口

TreeSet集合排序的两种方式:

第一种方式让元素自身具备比较性。也就是元素需要实现Comparable接口,重写compareTo 方法。

 

这种方式也作为元素的自然排序,也可称为默认排序。

compareTo 方法:this和参数的比较。

 

  1. 返回整数  this比参数大 (this排在参数后面)
  2. 返回负数  this比参数小 (this排在参数前面)
  3. 返回零    this和参数相等(认为是重复数据)

(2)Comparator接口

当元素自身不具备比较性,或者元素自身具备的比较性不是所需的。

那么这时只能让容器自身具备。

 

定义一个类实现Comparator 接口,重写compare方法。并将该接口的子类对象作为参数传递给TreeSet集合的构造方法。

Comparable比较方式,及Comparator比较方式同时存在,以Comparator

比较方式为主。

 

compare方法比较规则:

  1. 返回整数   参数1大于参数2 (参数1排在参数2的后面)
  2. 返回负数   参数1小于参数2 (参数1排在参数2的前面)
  3. 返回零     参数1等于参数2 (认为是重复数据)

TreeSet去重:

情况1:  

      当存入的数据是根据类型本身实现 Comparable接口方式比较大小,判断重复就是根据重写的compareTo方法。如果返回的是0 则认为是重复数据。

情况2: 当存入对象本身没有比较大小能力,而是根据比较器比较大小时,根据比较器中的compare方法的返回值来决定是否重复。返回0则认为是重复数据。

 

操作集合的工具类 Collections了解

Collections常用功能:大部分功能都是list的

List排序:sort方法

Collection元素搜索:binarySearch方法

改变Collection中的元素:addAll方法

  1. int  binarySearch(List<E> list, E e ):在一个有升序顺序的List集合中,通过二分查找寻找元素e的索引
  2. fill(List<E> list, E e):将list集合中的所有元素都填充为元素e
  3. int frequency(Collection<E> c, E e):返回在集合c中的元素e的个数
  4. max、min:获取集合的最大值或者最小值
  5. replaceAll(List<E> list, E oldVal, E newVal):将集合list中的所有指定旧元素oldVal都替换成新元素newVal
  6. reverse(List<E> list):将参数集合list进行反转
  7. shuffle(List<E> list):将list集合中的元素进行随机置换
  8. swap(List<E> list, int a, int b):将a索引和b索引的元素进行交换
  9. synchronizedXxx方法系列:将一个线程不安全的集合传入方法,返回一个线程安全的集合

 

 

********泛型********了解

  1. 泛型类

格式

 class 类名<泛型类型1,泛型类型2,...>{

 

}

 说明

1、类名后面跟着的泛型类型,是泛型的声明,一旦泛型声明出来,就相当于这个类型成为了已知类型,这个类型就可以在整个类中使用。

2、泛型的声明名称,只需要是一个合法的标识符即可,但是通常我们使用单个大写字母来表示,常用字母:T、W、Q、K、V、E。

3、泛型确定的时机:将来在使用这个类和创建对象的时候。

2、泛型方法

格式

修饰符 <泛型声明1, 泛型声明2,.....> 返回值类型 方法名称(参数列表) {

}

说明

  1、在方法上声明的泛型,可以在整个方法中,当做已知类型来使用。

  2、如果【非静态】方法上没有任何泛型的声明,那么可以使用类中定义的泛型

  3、如果【静态】方法上没有任何的泛型声明,那么就不能使用类的泛型,连类中定义的泛型,也不能使用,因为类中的泛型需要在创建对象的时候才能确定。所以【静态】方法想使用泛型,就必须在自己的方法上单独声明。

3、泛型接口

格式

interface 接口名称<泛型类型1, 泛型类型2,...> {

}

说明

  1、在接口声明上,定义好的泛型,可以在整个接口中当做已知类型来使用。

  2、泛型接口被其他类实现的时候,有两种实现方式:  

    (1)声明的类不再是一个泛型类,而是一个确定了泛型的类,格式如下:       class 实现类类名 implements 接口名<具体类型> {

        所有的泛型类型都已经被确定

}

    (2)声明的类还是一个泛型类,泛型的类型和接口的泛型一致,格式如下:

      class 实现类类名<泛型标识符1> implements 接口名<泛型标识符1> {

       所有的方法还都是可以使用泛型标识符的方法

}

 

泛型通配符

? extends E: 接收E类型或者E的子类型。

? super E: 接收E类型或者E的父类型。

泛型的好处

  1、提高了数据的安全性,将运行时的问题,提前暴露在编译时期

  2、避免了强转的麻烦

注意事项

  1、前后一致:在创建对象时,赋值符号前面和后面的类型的泛型,必须一致。

  2、泛型推断:如果前面的引用所属的类型已经写好了泛型,后面创建对象的类型就可以只写一个尖括号,尖括号中可以不写任何内容。<>特别像菱形,称为“菱形泛型”,jdk1.7特性。

如何写一个方法,调用者传递什么类型的变量,该方法就返回什么类型的变量?

实现一:

由于无法确定具体传递什么类型的数据,那么方法的形参就定义为Object类型,返回值也就是Object类型。但是使用该方法时需要强制类型转换。

当不进行强制类型转换能否写出该功能?

 

目前所学的知识无法解决该问题。

就需要使用泛型类解决。

使用的泛型的自定义来解决以上问题。

 

 

 

********栈(Stack)********了解

常用方法:            

boolean

empty()
测试堆栈是否为空。

E

peek()
查看堆栈顶部的对象,但不从堆栈中移除它。

E

pop()
移除堆栈顶部的对象,并返回该对象作为此函数的值。

E

push(E item)
把项压入堆栈顶部。

int

search(Object o)
返回对象在堆栈中的位置,以 1 为基数。

 

 

 

********Map(映射)********

Map:双列集合的顶层接口。

Map是一个以键(key)值(value)对形式存储数据的容器。

特点

Map 是一个接口,但不是Collection的子接口。

Map以键值对的形式存储数据,每个键(key)对应一个值(value)。

Map 中的键不能重复(唯一)。(如果键重复的话,就以最后一个为准,前面的相同键的键值对都被覆盖)

Map 中的值可以重复。

主要实现类 HashMap Hashtable TreeMap .

常用方法

put(K key, V value)  向Map中添加数据

putAll(Map<? extends K,? extends V> m) 向Map中添加另一个Map集合。

isEmpty()  Map中是否包含数据

size() Map中包含键值对的个数

get(key) 根据key获取value

clear() 清空Map

V

remove(Object key)

如果存在(从可选的操作),从该地图中删除一个键的映射。

default boolean

remove(Object key, Object value)

仅当指定的密钥当前映射到指定的值时删除该条目。

containsKey(key) 判断Map中是否包含key

containsValue(value) 判断Map中是否包含value

keySet() 返回Map中所有key 组成的Set集合

values() 返回Map中所有value组成的集合 (返回值Collection类型)

entrySet() 返回此映射中包含的映射关系的 Set 视图

 

 

********Map-->HashMap********

HashMap是Map接口的最常用实现类,底层是哈希表形式存储的,非线程安全的,允许有null键值对。

Map遍历

方式一:使用keySet()方法

  1. 获取Map集合中的所有键,放到一个Set集合中,遍历该Set集合,获取到每一个键,根据键再来获取对应的值。【根据键获取值】
  2. 获取Map集合中的所有键

Set<K> keySet()

方式二:使用entrySet()方法

获取Map集合中的所有键值对对象(Entry),到Set集合中,遍历Set集合,拿到的是每个键值对对象(Entry),从这个对象中分别获取键和值。【根据键值对对象获取键和值】

根据Map集合获取所有的键值对对象,到一个Set集合中

  Set<Map.Entry<K, V>>  entrySet()

 

Entry是Map接口中的内部接口,访问的方式:Map.Entry

 

Entry的常用方法:

   getKey()获取当前键值对对象的键

   getValue()获取当前键值对对象的值

 

********Map-->HashTable********

Hashtable是一个比较古老的类(从JDK1.0开始),特点是线程安全的,不允许有null键.

用法和HashMap相同,基本被HashMap替代

面试常见问题HashMap和Hashtable的区别?

HashMap: 线程不安全,允许null键值对,出现版本不同(1.2)),命名规范

Hashtable: 线程安全,不允许null键值对,1.0,命名不规范

 

 

********Map-->TreeMap********

特点:会根据key值进行升序排列。

 

******HashMap-->LinkedHashMap******

是HashMap的一个子类。

和HashMap的不同之处在于,具有可预知的迭代顺序,存储键值对的顺序和遍历集合时取出键值对的顺序一致。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值