Java学习14/15(集合List)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习14/15(集合List)相关的知识,希望对你有一定的参考价值。
断断续续的java学习(14/15)
要学的东西好多啊啊啊啊
第十四天/十五天
类在强制类型转换的过程中,如果是类转换成接口类型,那么 类和接口之间不需要存在继承关系,也可以转换
集合
1.集合实际上回就是一个容器,可以来容纳其他类型的数据。集合为什么说在开发中用的多?
集合是一个容器,是一个载体,可以一次容纳多个对象
在实际开发中,假设连接数据库,数据库中有10条记录,那么假设把10条记录查询出来,在java程序中会将10条数据封装成十个java对象,
然后将10个java对象放到一个集合中,将集合传到前端,然后遍历集合,将数据一个一个展现出来
2. 集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址,或者说集合中存储的是引用
list.add(100); //自动装箱Integer
注意:
集合在java中本身是一个容器,是一个对象,集合中任何时候存储的都是“引用”
3.在java中每一个不同的集合,底层会对应不同的数据结构。往不同的集合中存储元素,等于将数据放到了不同的数据结构中。
什么是数据结构? 数据存储的结构就是数据结构。不同的数据结构,数据存储方式不同,例如:
数组、二叉树、链表、哈希表...都是常见的数据结构
使用不同的集合等同于使用了不同的数据结构
在这一章,你需要掌握的不是数据结构,java中已经将数据结构实现了,已经写好了常用的集合类,你只需要掌握怎么用,什么情况下选择哪一种集合
4. 集合在java.util包下,所有的集合类和集合接口都在这个包下
5.在java中集合分为两大类:
一类是单个方式存储元素:
单个方式存储元素,这一类集合中超级父接口:java.util.Collection;
一类是以键值对的方式存储元素:
以键值对的方式存储元素,这一类集合中超级父接口:java.util.Map; (key-->value)
6.第一类集合的父接口是 Iterable (意思是可迭代的,可遍历的,所以集合元素都是可迭代的,可遍历的)
所有集合继承Iterable的含义是,所有集合都是可迭代的
Iterator it = (collection 对象).Iterator();
//集合的对象调用父类Iterable中的方法Iterator(),得到了迭代器对象it,
//迭代器中有hasNext(),next(),remove()三个方法,用它们完成集合遍历
//Iterator和Collection是关联关系,has a
7.集合下面有很多子接口,主要看List和Set
8.关于List:
List集合存储元素特点:有序可重复,存储的元素有下标,有序是存进去是这个顺序,取出来还是这个顺序,不是大小顺序排序。有序是因为List集合都有下标,下标从0开始,以1递增
Set集合存储元素特点:无序不可重复,无序表示存进去是这个顺序,取出来就不是这个顺序了,另外Set中元素没有下标
9.List下有实现(like a)的类,主要学ArrayList,LinkedList,Vector
ArrayList集合底层采用了数组这种数据结构,非线程安全的
LinkedList集合底层采用了双向链表数据结构
Vector底层采用了数组数据结构,线程安全的;但是效率较低,现在保证线程安全有别的方案,所以Vector使用较少了
10.Set中的类:HashSet
HashSet在new的时候,实际上底层创建了一个HashMap集合,说明了向HashSet集合中存储元素,实际上是存储到了HashMap集合中的key部分了。HashMap集合是一个哈希表数据结构
11.Set中有一个子接口:SortedSet,该接口下有一个实现类:TreeSet
TreeSet集合底层实际上是一个TreeMap,new TreeSet集合的时候,底层实际上是new了一个TreeMap集合,往TreeSet集合放数据,实际上放到了TreeMap集合中的key部分了;TreeMap集合底层采用了二叉树数据结构
SortedSet继承了Set,因此也是无序可重复,但是放在SortedSet集合中的元素可以自动排序,我们称为可排序集合。放到该集合中的元素是自动按照大小顺序排序的
12.Map集合
1)Map集合和Collection集合没有关系
2)Map集合以key和value的这种键值对方式存储元素
3)key和value都是存储java对象的内存地址
4)所有Map集合的key特点:无序不可重复;Map集合的key和Set集合存储元素特点相同
5)Map集合key就是一个Set集合,往Set集合放数据,实际上放到了Map结合的Key部分
13.Map集合两个实现类
HashMap底层是哈希表数据结构,是非线程安全的
Hashtable底层也是哈希表,是线程安全的,效率较低,和上面的数组原因一样
Hashtable有一个子类Properties,被称为属性类(以后开发会用),它是线程安全的,因为它继承Hashtable,并且它的key和value只支持String类型,不支持其他类型
14.Map中有一个子接口SortedMap,它有个实现类是TreeMap
SortedMap集合key存储元素的特点:首先是无序不可重复的,另外放在SortedMap集合key部分的元素会自动按大小顺序排序,称为可排序的集合
TreeMap集合底层的数据结构是一个二叉树
Collecion
没有用“泛型”之前,Collection中可以存储Object的所有子类型
使用了“泛型”之后,只能存储某个具体的类型
常用方法:
1.boolean add (Object e);往集合中添加元素
2.int size();获取集合中元素的个数,不是获取集合的容量
3.void clear(); 清空集合
4.boolean contains(Object o); 判断当前集合中是否包含元素o,包含返回true,不包含返回false
5.boolean remove(Object o); 删除集合中的某个元素
6.boolean isEmpty(); 判断集合是否为空
7.Object[] toArray(); 转换成数组(了解,使用不多)
关于集合遍历/迭代
第一步:获取集合对象的迭代器对象Iterator
Iterator it = c.iterator();
第二步:通过以上获取的迭代器对对象开始进行迭代/遍历
以下两个方法是迭代器对象Iterator的方法:
boolean hasNext() 如果仍有元素可以迭代,则返回true
Object next() 返回迭代的下一个元素
存进去是什么类型,取出来是什么类型,只不过是输出的时候会转换成字符串输出
在没有加元素之前获得迭代器,指向的是集合中没有元素状态下的迭代器
注意:集合结构只要发生改变,这个迭代器必须重新获取,如果没有重新获取,会出现:ConcurrentModificationException异常
获取的迭代器对象,迭代器用来遍历集合,此时相当于对当前集合状态拍了一个快照,迭代器迭代的时候会参照这个快照进行迭代
如果用集合中remove删除元素,没有通知迭代器,导致快照和原集合状态不同,就会出现异常
用迭代器的remove方法删除元素,会将快照中的元素也删除,会自动更新迭代器,更新集合(删除集合中的元素),所以不会有问题
在迭代元素的过程中,一定要用迭代器Iterator的remove方法删除元素
关于Collection中的contains/remove方法
深入Collection集合的contains方法:
boolean contains(Object o)
判断集合中是否包含某个对象o
如果包含返回true, 如果不包含返回false。
contains方法是用来判断集合中是否包含某个元素的方法,那么它在底层是怎么判断集合中是否包含某个元素的呢?
调用了equals方法进行比对。
equals方法返回true,就表示包含这个元素。
结论:存放在一个集合中的类型,一定要重写equals方法。
remove()方法底层也调用了equals()方法
List
1.List存储元素特点:有序可重复,集合中元素有下标,从0开始,以1递增
2.List接口特有的常用的方法:
void add(int index, Object element)
//在列表指定位置插入指定元素(第一个参数是下标),用的不多,因为效率比较低,一般使用集合中add方法,向集合末尾添加元素
Object get(int index) //根据集合下标取元素,通过此方法可以遍历List集合,Set中不行
int indexOf(Object o) //获取指定对象第一次出现的索引
int lastIndexOf(Object o) //获取指定对象最后一次出现的索引
Object remove(int index) //删除指定位置的元素
Object set(int index, Object element) //修改指定位置的元素
计算机英语
增:add、save、new
删:delete、drop、remove
改:update、set、modify
查:find、get、query、select
ArrayList
1.ArrayList默认初始化容量是10(底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10)
2.底层是Object类型的数组
3.有参构造方法可以创建一定容量的集合
4.ArrayList集合的扩容:增长到原容量的1.5倍;
ArrayList集合底层是数组,怎么优化?
尽可能少的扩容,因为数组扩容效率较低,建议给定一个预估计的初始化容量,减少数组的扩容次数,这是ArrayList集合比较重要的优化策略
5.面试官经常问的一个问题:
这么多集合中,用哪个集合比较多?
答:ArrayList集合,因为往数组末尾添加元素,效率不受影响,另外,我们检索/查找某个元素操作比较多
(为什么检索效率高:每个元素占用空间大小相同,内存地址是连续的,知道首元素内存地址,然后知道下标,通过数学表达式可以计算出元素的内存地址,所以检索效率高)
6.数组缺点:
随机增删元素效率比较低
另外数组无法存储大数据量(很难找到一块非常大的连续的内存空间)
7. ArrayList还有一个构造方法可以传进去一个集合,可以将传进去的集合转换成List集合
8. ArrayList是非线程安全的
二进制位运算
位运算符 >> <<
二进制右移一位 >>1 ; 右移两位>>2
链表数据结构
单向链表基本单元:Node
每一个node都有两个属性:存储的数据和下一个节点的内存地址
末尾节点的第二个属性是null(因为没有下一个节点了)
链表的优点:由于链表上的元素在空间储存上内存地址不连续,随机增删元素的效率较高(因为增删元素不涉及大量的元素位置)
缺点:不能通过数学表达式计算被查找元素的内存地址,查询效率较低,每次查找某个元素的时候都需要从头节点开始往下遍历
LinkedList中是双向链表,没有初始化容量
最初这个链表中没有任何元素,first和last引用都是null
不管是LinkedList还是ArrayList,以后编写代码时不用关心具体是哪个集合,因为我们面向接口编程,调用的方法都是接口中的方法
链表中的元素在空间储存上,内存地址不连续
Vector
1.底层是一个数组
2.初始化容量是10
3.怎么扩容的?
扩容之后是原容量的二倍
4.Vector中的方法都是线程同步的,都带有synchronized关键字,是线程安全的。效率比较低,使用较少了
5.怎么将一个线程不安全的ArrayList转变为线程安全的?
使用集合工具类:
java.util.Collections;
java.util.Collection 是集合接口
java.util.Collectinos 是集合工具类
Collection collection = new ArrayList();
collection.add(1200);//自动装箱,实际上放进去的是一个对象的内存地址;Integer x = new Integer(1200);
collection.add(1);
collection.add(2);
Iterator iterator = collection.iterator();
while(iterator.hasNext()){
Object i = iterator.next();
iterator.remove();
System.out.println(i); // 1200 1 2
}
//迭代器中删除元素会同时删除集合中的元素,所以输出为0
System.out.println(collection.size()); //0
以上是关于Java学习14/15(集合List)的主要内容,如果未能解决你的问题,请参考以下文章