集合与泛型

泛型

一、泛型的定义

       泛型是Java5引进的新特征,是类和接口的一种扩展机制,主要实现参数化类型机制。在Java集合框架中大多数的类和接口都是泛型类型。简单来说,泛型就是带一个或多个类型参数的类或接口。

class 类名<类型参数> { }
泛型类型的使用与方法调用相似,方法调用需要向方法传递参数,同样使用泛型也需要传递一个类型参数,也就是说用某个具体的类型替换类型参数。下面是一个泛型类型的使用例子:

        public static void main(String[] args) {
            Node <Integer> intNode=new Node<>();//由于编译器能够从上下文中推断出泛型参数的类型,所以现在再创建泛型类型时可以使用一对<>来创建。
            intNode.set(new Integer(9));
            System.out.println(intNode.get());
            intNode.showType();
        }

注意:类型参数名一般使用单个大写字母。常用的类型参数名有E(表示元素),K(表示键),N(表示数字),T(表示类型), V(表示值)等。泛型可能具有多个类型参数,但是在类或接口的声明中,每个参数名都必须是唯一的。并且它的类型只能是引用数据类型,不能是基本数据类型。同时泛型可能具有多个类型参数,但在类或接口的声明中,每个参数名必须是唯一的。

二、泛型方法

       泛型方法(generic method)是带类型参数的方法。类的成员方法和构造方法都可以定义为泛型方法。泛型方法的定义与泛型类型的定义类似,但类型参数的作用域仅限于声明的方法和构造方法内。泛型方法可以定义为静态的和非静态的。并且,对于泛型方法,必须在方法返回值前指定泛型。

三、通配符(?)

       当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

四、有界类型参数

在JAVA的泛型中可以指定一个泛型的上限下限

泛型上限:类型名称 <? extends 类 > 对象名称 ----- 只能接收该类型及该类型的子类

泛型下限:类型名称 <? super 类 > 对象名称 ------ 只能接收该类型及该类型的父类型

五、类型擦除

       当实例化泛型类型时,编译器使用一种叫类型擦除(type erasure)的技术转换这些类型。在编译时,编译器将清除类和方法中所有与类型参数有关的信息。类型擦除可让使用泛型的Java 应用程序与之前不使用泛型类型的Java类库和应用程序兼容。

集合

一、集合的定义

集合是指集中存放一组对象的一个对象,它相当于一个容器,提供了保存,获取和操作其他元素的方法。集合能够帮助Java程序员轻松管理对象。Java集合框架由Collection和Map构成。

二、迭代器

迭代器是一个可以遍历集合中每个元素的对象。调用集合对象的iterator()方法可以得到Iterator对象,在调用Iterator对象的方法就可以遍历集合中的每个元素。它是速度最快的。它定义了以下3种方法:
next(), hasNext(), remove()

可以认为Java迭代器位于两元素之间

当调用next 时,迭代器越过下一个元素,并返回越过的元素的引用,remove方法则删除上一次调用next返回的元素

三、Collection 接口
有些Collection的实现类可以存放重复元素,有些不可以
Collection的实现接口 List 是有序的, Set 是无序的
Collection 没有直接的实现子类,是通过它的子接口List 和 Set 来实现的
Collection接口的元素遍历方式
1.使用迭代器Iterator
2.增强for循环(简化版的iterator)

四、List接口

定义:List接口是Collection接口的子接口,实现一种线性表的数据结构。存放在List中的所有元素都有一个从0开始的下标,我们通过下标来访问List当中的元素。他可以包含重复的元素。它分为ArrayList(对象引用的变长数组,支持泛型,值有顺序)和LinkedList(链表型的数据结构,支持泛型,只有顺序)。

List的常用方法:

E set(int index, E element):修改指定下标处的元素。
void add(int index, E element):将指定元素插入到指定下标处。
E remove(int index):删除指定下标处的元素。
abstract boolean addAll(int index, Collection<? extends E> c):在指定下标处插入集合c中的全部元素。
int indexOf(Objecto):查找指定对象第一次出现的位置。
int lastlndexOf(Object o):查找指定对象最后一次出现的位置。
List<E> subList(int from, int to):返回从from到to元素的一个子线性表。
default void replaceAll(UnaryOperator<E>operator):将操作符应用于元素,并使用其结果替代每个元素。

List 从Collection 接口继承的操作与Collection 接口类似,但有的操作有些不同。例如,remove0方法总是从线性表中删除指定首次出现的元素;addO和addAllO方法总是将元素插入到线性表的末尾

List 实现类 ArrayList
底层维护的是一个动态的数组
线程不安全的, Vector与其基本等同,除了Vector是线程安全的
创建和扩容流程 Debug
调用无参构造器时,车市elementData容量为零,第一次添加元素时扩容为10, 若再次扩容,则扩容1.5倍
调用有参构造器时指定容量,则出书elementData容量为所指定的大小,若再次扩容,也是扩容1.5倍
List 实现类 LinkedList
底层维护了一个双向链表
LinkedList中维护了两个属性first, last分别指向 首节点和尾节点
添加和删除效率高

五、Set接口

定义:Set接口是Collection接口的子接口,Set接口对象类似与数学上的集合概念,其中不允许有重复的元素。因为Set接口没有定义新的方法,只包含从Collection接口继承的方法。

HashSet():创建一个空的散列集合,该集合的默认初始容量是16,默认装填因子(loadfactor)是0.75。装填因子决定何时对散列表进行再散列。例如,如果装填因子为0.75(默认值),而表中超过75%的位置已经填入元素,这个表就会用双倍的桶数自动地进行再散列。对于大多数应用程序来说,装填因子为75%是比较合理的。HashSet(Collection c):用指定的集合c的元素创建一个散列集合。
HashSet(int initialCapacity):创建一个散列集合,并指定集合的初始容量。
HashSet(int initialCapacity, float loadFactor):创建一个散列集合,并指定的集合初始容量和装填因子。

六、Queue接口

Queue 接口除了提供Collection的操作外,还提供了插入、删除和检查操作。Queue接口的常用方法如下:
 boolean add(E e):将指定的元素e插入到队列中。EremoveO:返回队列头元素,同时将其删除。

E element():返回队列头元素,但不将其删除。
boolean offer(E e):将指定的元素e插入到队列中。
Epoll():返回队列头元素,同时将其删除。
Epeek():返回队列头元素,但不将其删除。

【前三个操作失败抛出异常,后三个操作失败不抛出异常】

七、Map接口

Map家族中使用频率非常高的成员。
底层采用数组+链表+红黑树(链表长度大于阈值时转为红黑树,默认阈值为8)存储元素,与HashSet相似,不保证元素的添加顺序。
HashMap的key值不可重复,可取null值,但也只能有一个null值,任意引用类型的数据都可作为key值传入,但是要重写hashCode()和equals()方法以确保传入键值的唯一性。

HashMap的put操作:

~判断数组是否为空,如果为空则进行扩容;

~根据key值得到该对象对应的哈希值,然后根据哈希算法(高位运算+取模)计算得到待插入的索引位置;

~若该索引位置尚未存储数据,直接插入;否则判断该位置的首个元素是否和待插入对象相同,相同则直接覆盖value值,添加成功;

~若该索引位置为链表,遍历链表,若有相同元素直接覆盖,若无判断链表长度是否大于8,大于8则转为红黑树进行添加操作,否则直接在链表中添加;

~若该索引位置为红黑树,则在树中插入键值对,有相同元素覆盖即可。

~添加前后都会进行容量判断,看是否需要扩容。
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值