泛型、迭代器、List集合

一、泛型Generics

JDK1.5之后出现的。

1.概念:广泛的类型——>声明要存储的类型是什么。

2.作用:存入到容器中的元素,Object类型(向上转型)。当获取的时候,需要手动的向下转型,降低效率,容易出错。

3.使用:在创建集合的时候,使用泛型来指明该容器中,能够存储的数据类型。

4.目的:指定集合中存储的元素的数据类型,保护容器中的数据的类型的安全。

    String-->Object

    Integer-->Object

    Person-->Object

    String-->String

    Integer-->Integer

    Person-->Person

5.语法:

    容器<数据类型> 容器对象 = new 容器<>();

例如:Collection<String> c2 = new ArrayList<>();

          Collection<Person> c4 = new ArrayList<>();

注意点:因为集合仅限于存储引用类型,所以声明泛型不能直接写基本数类型,需要写对应的包装类。

()-->方法

[]-->数组

{}-->....

<>-->泛型

5.2、泛型应用在类上。

声明一个类的时候使用<>,限制数据类型,泛型作用在类上。普通方法和普通的属性。属于对象的,可以直接使用该泛型。但是不能给静态用。因为作用在类上的泛型,当对象被创建的时候确定的。

class 类名<T>{

    //T这个类型,当创建对象的时候决定好。

}

泛型擦除:如果创建对象的时候,没有指明泛型,那么该类型T——>Object类型。

5.3、泛型作用在静态方法上

方法的声明上使用泛型的声明<>。

类的静态方法如果使用泛型,需要单独进行泛型的声明,声明泛型要写在static关键字之后,返回值类型之前。

//3.<M>,静态方法上自己独立声明泛型,不能使用类的。

    publicstatic<M>Mtest(Mm){

        System.out.println(m);

        returnm;

    }


6、泛型的限定:集合中

?:代表了任意集合中可以存储任意类型,区分于Object

List<?>,List<Object>

List<?>指代可以存储任意泛型类型的集合

List<Object>集合中的对象,就是Object类型,其他类型的对象会自动转为Object类型。

?extends T:限定了上限

接收集合的泛型:中可以存储T,以及T的子类类型。

?super T:限定了下限

接收集合的泛型:可以是T,以及T的父类。


7、不允许使用泛型的地方

静态属性:private static T member;//错误的

创建T的实例:T t = new T();//错误

自定义异常,不能使用泛型

class MyException<T> extends Exception


8.数组的语法格式:

数据类型[] 数组名= new 数据类型[长度];

int[] arr = new int[5];

arr[0]-->int

Arrays.toString(arr);//--->数组的元素

集合对象直接打印,不显示集合的地址,直接显示集合中存储的元素。集合对象,都重写了toString();

二、迭代器Iterator

1.定义:集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历)

    演示遍历集合

2.迭代器使用:(接口类型)(属于Collection接口)

step1://先在要遍历的集合上,获取迭代器对象

c1.iterator();--->Iterator it

step2:判断迭代器对象之后是否有元素

it.hasNext();--->boolean

step3:获取该元素:

it.next();-->元素

实例代码:

    Collection<String> c = new ArrayList();

    Iterator<String> it = c.iterator();

    while (it.hasNext()) {

        String s1 = it.next();

        System.out.println(s1);

    }

3.注意点:

(1、每次迭代获取(调用next())前,应该先判断是否有这个元素(hasNext()),如果有再获取,如果没有就不要获取,如果强行获取,就报错:java.util.NoSuchElementException

(2、一个迭代器对象,从头执行到最后就不能再次使用,因为后面没有元素,迭代不出来了。

(3、迭代器在工作期间,集合本身不要去更改集合的结构。但是迭代器对象自己可以删除。(功能慎用)



三、List接口(重点中重点!!!!!)

作为Collection接口的子接口,也是一种容器。但是有自己的独特的存储特点。

1、定义

    List集合是有序的,可以储存重复的数据

    List集合通过记录元素在集合中的位置来准确的查找元素

2、List集合体系

    ArrayList    底层使用数组(线程不安全)

    LinkedList    底层使用链表

    Vector    底层使用数组(线程安全的,不推荐使用)

3、新增了自己特有的功能方法:都是和下标有关系的。

set(index,E)-->指定位置替换元素

get(index)-->E,获取指定位置的元素

add(index,E)-->指定位置添加元素

remove(index)-->根据位置进行删除

indexOf()-->int,搜索指定的元素,返回下标,如果没有就返回-1

subList(fromIndex,endIndex)-->List,截取子集合

遍历一个List接口中的所有元素:

    for-each,增强for循环

    Iterator,迭代器

    普通的for循环,结合get()方法。


四、ArrayList实现类

作为List接口的实现类,将接口中的方法全部实现。

1、定义

    底层:数组的结构来实现的。也会有人叫动态数组。(最大的特点:内存连续

    储存的元素是有序的,而且可以重复存储, 通过数组角标来查询更改元素,速度非常快

    由于每次增删都要改动数组中的角标,所有导致增删效率低下

2、ArrayList的增删改查原理

    ArrayList 集合初始化会有一个默认长度是10的数组, 内部还有一个记录当前元素个数的变量, 当储存的元素个数超过数组长度之后,容量就会扩充一半 

    当我们去查询集合中的元素时, 需要提供给集合一个角标值, 然后通过这个角标值查找集合中的元素

    当我们去删除一个元素的时候, 集合就会根据角标删除这个元素,并且改动其他元素的位置,这就是导致增删缓慢的原因

    其实如果我们是连续往集合尾部插入数据的话, 速度其实是非常快的, 因为其他元素的位置不需要改动,但是如果我们插入数据的位置是数组的前面或者中间,速度就会有明显的降低

3、构造方法

    ArrayList()    构造一个初始化容量为10的空列表

    ArrayList(Collection<? exends E>  e)    构造一个包含执行集合元素的列表

    ArrayList(int initialCapacity)    构造一个具有指定初始容量的空列表

4、常用方法

boolean add(E e)    将指定的元素添加到此列表的尾部

void add(int index,E element)    将指定的元素插入此列表中的指定位置

boolean contains(Object o)    如果此列表中包含指定的元素,则返回true

E get(int index)    通过角标查找元素

int indexOf(Object o)    返回此列表中首次出现的指定元素的索引, 或如果没有则返回 -1

int lastIndexOf(Object o)  返回此列表中最后一次出现的指定元素的索引(从后先前查)没有返回-1

E remove(int index)  移除此列标中指定位置上的元素

boolean remove(Object o)    移除此列表中首次出现的指定元素(如果存在)

E set(int index , E element)    用指定元素替代此列表中指定位置上的元素,返回原来的元素

int size()    返回此列表中的元素数

理解为ArrayList相当于一个可变长度的数组,访问遍历效率较高。增加,删除元素,效率较低。

JDK1.2的版本的类。


五、LinkedList实现类

LinkedList实现类,区别于ArrayList,除了实现List接口,还实现了Deque接口。

LinkedList实现类:

实现的接口:

List接口------------------------------------------------->Collection

Deque(双端队列)接口--->Queue(队列)接口--->Collection

queue:队列。排队,队列

deque:双端队列,全名:double-ended queue


模拟栈的结构:后进先出(LIFO),栈顶元素,

    push(),压栈,入栈,pop(),弹栈,出栈

模拟队列的结构:先进先出(FIFO),队头元素

    offer(),poll()

1、定义

    底层实现:采用双向链表的结构实现

    这个集合中的每个元素都被封装到一个叫Node的内部类中, 然后记录上一个元素和下一个元素的地址,通过手拉手形成一个链条

    增删快, 查询慢

2、增删改查的原理

    当需要去查询LinkedList集合中的元素时,需要从最开始的元素查找起,然后一层一层往后找,直到找到该元素,这样的动作十分消耗性能

    当需要去删除元素的时候, 我们只需要将被删除元素两端的元素重新连接到一起,或者新增的时候将新元素和左右两边的元素连起来就可以了

3、构造方法

    LinkedList()    构造一个空列表

    LinkedList(Collection<? extends E> e)    构造一个包含指定collection中元素的列表

4、常用方法

    E remove()    获取并移除此列表的头

    E poll() 获取并移除此列表的头

    E peek() 获取但不移除此列表的头


六、ArrayList, LinkedList 及Vector集合之间的区别

1、线程安全

    Vector : 线程安全

    ArrayList, LinkedList : 线程不安全

2、实现方式

    LinkedList : 链表

    ArrayList,Vector : 数组

3、扩容

    ArrayList和Vector使用数组实现, 当数组长度不够,内部会创建一个更大的数组

    LinkedList 不存在这方面的问题

4、速度

    ArrayList 查改块, 增删慢

    LinkedList 查改慢, 增删快


七、ArrayList和LinkedList总结

1.ArrayList 是有序插入  LlnkedList 是无序插入。

    比较谁查找快: 要考虑数据量 和是否有无序插入

        如顺序插入 如果是尾部添加, ArrayList反而更块

        乱序插入  LlnkedList快


八、拓展1

  数组结构:在内存中连续空间。存储的数据的组织特点。

线性表,链表,树。。。。

栈:Stack,这种数据结构的特点?

last In First Out,简称LIFO,后进先出。

队列:queue,

First in First out,简称FIFO,先进先出。

拓展2

Vector:向量

对比ArrayList,LinkedList,Vector实现类

A:ArrayList,底层采用数组结构的实现的。(内存中连续空间)。jdk1.2

    只实现了List接口,功能都是List接口中规定的。

    优缺点:

        优点:遍历访问元素,效率很高

        缺点:插入或删除元素,效率相对低。

B:LinkedList,底层采用双向链表结构实现的。(元素在内存中不挨着,元素之间的指向)。jdk1.2

    实现了List接口的同时,还实现了Deque接口,所以有这两个接口中的功能。

    优缺点:

        优点:插入或删除元素,效率很高。

        缺点:遍历访问元素,效率相对低。

注意点:

    如果一个集合,频繁的添加或删除元素,建议选择LinkedList。

    如果一个集合,绝大多数的操作就是遍历查询,建议选择ArrayList。

    如果要模拟栈,队列等结构,建议选择LinkedList。

C:Vector,是ArrayList的前身。也是数组的结构。古老的类。从jdk1.0的版本就有了。

    线程安全,效率低,后来被ArrayList替代了。

    ArrayList和LinkedList都是线程不安全的,效率高。Collections工具类,可以获取线程安全的集合。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343