前段时听面试的人说这java数据这一块经常问到于是便作此总结,如有不对的地方请大佬指出,我们共同学习
一、数组
1数组的概念
数组就是同一种类型数据的集合,其实数组就是一个容器。有时候我们,有很多数据需要保存以便于后期使用,那么就可以使用数组,数组就是一种用于存储数据的方式。能存数据的地方我们称之为容器,容器里装的东西就是数组的元素。
2 数组的优点和缺点
数组的最大好处就是能都给存储进来的元素自动进行编号. 注意编号是从0开始。(也就是索引)用来方便操作这些数据。
例如 学生的编号,使用学号就可以找到对应的学生。
优点:
1、按照索引查询元素速度快
2、能存储大量数据
3、按照索引遍历数组方便
缺点:
1、根据内容查找元素速度慢
2、数组的大小一经确定不能改变。
3、数组只能存储一种类型的数据
4、增加、删除元素效率慢
5、未封装任何方法,所有操作都需要用户自己定义。
3 数组的特点
数组可以装任意类型的数据,虽然可以装任意类型的数据,但是定义好的数组只能装一种元素, 也就是数组一旦定义,那么里边存储的数据类型也就确定了。通过整型索引访问它的元素,并且长度一旦确认,不能长度不能改变。
4数组的内存分析
5数组中最常见的问题:
1.NullPointerException 空指针异常
原因: 引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法
2. ArrayIndexOutOfBoundsException 索引值越界。
原因:访问了不存在的索引值。
6数组的特殊性
(一)数组标识符是一个引用,指向堆中创建的一个真实对象,这个对象(数组)保存了指向保存其他对象的引用。
(二)数组中保存引用类型时保存的是对象引用,基本数据类型数组保存基本数据的值。
(三)数组的length只表示数组能够容纳多少元素,不能保存实际保存的元素个数。
(四)多维数组可以使用Arrays.deepToString()将多维数组转换成String。
(五)不能使用泛型创建数组,例如:
T []list=new T[size];//会报错
解决方法:
使用Object转型:
Object [] objs=new Object[size];
T []Objs=(T[])objs;
7注意点
int [] x=new int[3];
x 是什么类型?
任何一个变量都得有自己的数据类型。注意这个x 不是int 类型的 。int 代表的是容器里边元素的类型。那么x 是数组类型的。
二、集合
1集合的由来
当我需要保存许多对象时,我们首先想到了数组,但是数组只能放统一类型的数据,而且其长度是固定的,那怎么办呢?集合便应运而生了!
2集合是什么?
Java中集合就是一个用来存放对象的容器。
注意:
①、集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
②、集合存放的是多个对象的引用,对象本身还是放在堆内存中。
③、集合可以存放不同类型,不限数量的数据类型。
3数组和集合的区别
长度区别
数组不可改变
集合可以改变
内容区别
数组可以存放基本数据类型,也可以存放引用数据类型
集合只能存放引用数据类型
元素内容
数组只能存放一种数据类型
集合可以存放多种数据类型
4集合框架
集合图解
名称 数据类型 是否有序 是否可重复 线程是否安全 默认初始容量 是否Null 父级
Hasnset 哈希表 不保证 去重复 不同步 16 允许null Abstractset
LinkedHashSet 链表 无序 去重复 不同步 16 允许null hashset
TreeSet 红黑树 无序 去重复 不同步 / 不允许null Abstractset
ArrayList 数组 有序 允许重复 不同步 10 允许 AbstractList
LinkedList 双向链表 有序 允许重复 不同步 / 允许null AbstractSequentialList
Vector 数组 有序 允许重复 同步 / 允许null AbstractList
HashMap 键值对 有序 不允许 / 允许null AbstractMap
TreeMap
红黑树 有序 不允许 不同步 / 不允许null AbstractMap
Java集合框架主要由Collection和Map两个根接口及其子接口、实现类组成。
Collection
Collection接口是set、List和Queue接口的父接口,它基本操作:
add(Object o):增加元素
addAll(Collection c): 将指定 collection 中的所有元素都添加到此 collection 中
clear(): 移除此 collection 中的所有元素(可选操作)。
contains(Object o):是否包含指定元素
containsAll(Collection c):是否包含集合c中的所有元素
iterator():返回Iterator对象,用于遍历集合中的元素
remove(Object o):移除元素
removeAll(Collection c):相当于减集合c
retainAll(Collection c):相当于求与c的交集
size():返回元素个数
toArray():把集合转换为一个数组
http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
Set子接口
Set接口不允许包含相同元素,而从equals方法来判断的
HashSet类
1. HashSet概述:
HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。
2. HashSet的实现:
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成
(1)不能保证元素的排列顺序,加入的元素要特别注意hashCode()方法的实现。
(2)HashSet不是同步的,多线程访问同一步HashSet对象时,需要手工同步。
(3)集合元素值可以是null。
LinkedHashSet类
LinkedHashSet内部使用的是LinkHashMap,也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序。与HashSet相比,特点:
对集合迭代时,按增加顺序返回元素。
性能略低于HashSet,因为需要维护元素的插入顺序。但迭代访问元素时会有好性能,因为它采用链表维护内部顺序。
SortedSet接口及TreeSet实现类
SortedSet继承自Set,他根据对象的比较顺序(可以是自然顺序,也可以是自定义的顺序),而不是插入顺序进行排序;
TreeSet是SortedSet的唯一实现类,红黑树实现,树形结构,它的本质可以理解为是有序,无重复的元素的集合。
因为都是有序的,所以相应的就有get,remove和add方法。
TreeSet类是SortedSet接口的实现类。因为需要排序,所以性能肯定差于HashSet。与HashSet相比,额外增加的方法有:
first():返回第一个元素
last():返回最后一个元素
lower(Object o):返回指定元素之前的元素
higher(Obect o):返回指定元素之后的元素
subSet(fromElement, toElement):返回子集合
可以定义比较器(Comparator)来实现自定义的排序。默认自然升序排序。
List子接口
List子接口是有序集合,所以与Set相比,增加了与索引位置相关的操作:
add(int index, Object o):在指定位置插入元素
addAll(int index, Collection c):…
get(int index):取得指定位置元素
indexOf(Obejct o):返回对象o在集合中第一次出现的位置
lastIndexOf(Object o):…
remove(int index):删除并返回指定位置的元素
set(int index, Object o):替换指定位置元素
subList(int fromIndex, int endIndex):返回子集合
ArrayList
- ArrayList 是 java 集合框架中比较常用的数据结构了。继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。是一个可变数组,与Java中数组相比,它的容量是动态增长的,它继承自AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
- ArrayList继承AbstractList,实现了List,提供了对集合元素进行增、删、改、查等操作的方法。
- ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。
- ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
- ArrayList 实现java.io.Serializable接口,即ArrayList支持序列化,能通过序列化去传输。 6. 与Vector的不同之处在于,ArrayList的相关操作不是同步的,也就是说ArrayList的相关操作是线程不安全的,建议在单线程中使用。 ArrayList 底层是基于数组来实现容量大小动态变化的。
默认初始容量大小为 10;
完整的ArrayList的解析(源码级)
http://www.cnblogs.com/ITtangtang/p/3948555.html#info
Vector和ArrayList区别
这两个类都是基于数组实现的List类。
ArrayList是线程不安全的,而Vector是线程安全的。但Vector的性能会比ArrayList低,且考虑到兼容性的原因,有很多重复方法。
Vector提供一个子类Stack,可以挺方便的模拟“栈”这种数据结构(LIFO,后进先出)。
结论:不推荐使用Vector类,即使需要考虑同步,即也可以通过其它方法实现。同样我们也可以通过ArrayDeque类或LinkedList类实现“栈”的相关功能。所以Vector与子类Stack,建议放进历史吧。(没有深入研究)
LinkedList类
不像ArrayList是基于数组实现的线性表,LinkedList类是基于链表实现的。
另外还有固定长度的List:Arrays工具类的方法asList(Object… a)可以将数组转换为List集合,它是Arrays内部类ArrayList的实例,特点是不可以增加元素,也不可以删除元素。
Queue子接口
Queue用于模拟队列这种数据结构,实现“FIFO”等数据结构。通常,队列不允许随机访问队列中的元素。
Queue 接口并未定义阻塞队列的方法,而这在并发编程中是很常见的。BlockingQueue 接口定义了那些等待元素出现或等待队列中有可用空间的方法,这些方法扩展了此接口。
Queue 实现通常不允许插入 null 元素,尽管某些实现(如 LinkedList)并不禁止插入 null。即使在允许 null 的实现中,也不应该将 null 插入到 Queue 中,因为 null 也用作 poll 方法的一个特殊返回值,表明队列不包含元素。
基本操作:
boolean add(E e) : 将元素加入到队尾,不建议使用
boolean offer(E e): 将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常要优于 add(E),后者可能无法插入元素,而只是抛出一个异常。推荐使用此方法取代add
E remove(): 获取头部元素并且删除元素,不建议使用
E poll(): 获取头部元素并且删除元素,队列为空返回null;推荐使用此方法取代remove
E element(): 获取但是不移除此队列的头
E peek(): 获取队列头部元素却不删除元素,队列为空返回null
PriorityQueue类
PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按队列元素的大小重新排序。当调用peek()或者是poll()方法时,返回的是队列中最小的元素。当然你可以与TreeSet一样,可以自定义排序。
Deque子接口与ArrayDeque类
Deque代表一个双端队列,可以当作一个双端队列使用,也可以当作“栈”来使用,因为它包含出栈pop()与入栈push()方法。
ArrayDeque类为Deque的实现类,数组方式实现。方法有:
addFirst(Object o):元素增加至队列开头
addLast(Object o):元素增加至队列末尾
poolFirst():获取并删除队列第一个元素,队列为空返回null
poolLast():获取并删除队列最后一个元素,队列为空返回null
pop():“栈”方法,出栈,相当于removeFirst()
push(Object o):“栈”方法,入栈,相当于addFirst()
rem
oveFirst():获取并删除队列第一个元素
removeLast():获取并删除队列最后一个元素
实现List接口与Deque接口的LinkedList类
LinkedList类是List接口的实现类,同时它也实现了Deque接口。因此它也可以当做一个双端队列来用,也可以当作“栈”来使用。并且,它是以链表的形式来实现的,这样的结果是它的随机访问集合中的元素时性能较差,但插入与删除操作性能非常出色。
各种线性表选择策略
1.数组:是以一段连续内存保存数据的;随机访问是最快的,但不支持插入、删除、迭代等操作。
2.ArrayList与ArrayDeque:以数组实现;随机访问速度还行,插入、删除、迭代操作速度一般;线程不安全。
3.Vector:以数组实现;随机访问速度一般,插入、删除、迭代速度不太好;线程安全的。
4.LinkedList:以链表实现;随机访问速度不太好,插入、删除、迭代速度非常快。
https://www.cnblogs.com/nayitian/p/3266090.html
Map
java中的map集合使用键(key)值(value)来保存数据,其中值(value)可以重复,但键(key)必须是唯一,也可以为空,但最多只能有一个key为空,它的主要实现类有HashMap、LinkedHashMap、### TreeMap。
2、HashMap、LinkedHashMap、TreeMap区别及用法
1、HashMap
特点:保存元素时先进后出、无序性;查询效率比较高;key-value可以为null,但最多只能为一个null;不支持线程同步,即可以有多个线程同时写HashMap,可能导致数据不一致,如果需要同步可以使用Collection的synchronizedMap方法使其同步。
特点:LinkedHashMap内部是双向链表结构,保存了元素插入的顺序,Iterator遍历元素时按照插入的顺序排列,支持线程同步。
2、TreeMap
特点:保存元素key-value不能为null,允许key-value重复;遍历元素时随机排列。