数组是JAVA语言内置的数据类型,它是一个线性的序列,所以它可以快速的访问其他的元素。但是速度是要有代价的,当你创建了一个数组之后,它的容量就固定了,而且在其生命周期里是不能改变的。还有一点,JAVA里面的数组是会做边界检查的,所以当你越界访问时,会抛出RuntimeException,当然边界检查是以牺牲效率为代价的。数组与其它容器类的区别体现在三个方面:效率、类型识别和可以持有primitives。
JAVA里面提供的其他容器还包括List,Set和Map。他们处理对象的时候就好像这些这些对象都没有自己的类型一样,容器将它所含的元素都看成是JAVA中所有类的根类Object类型的,这样我们只需创建一种容器,就能把所有的类型的对象全部放进去。
数组和集合的区别
- 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)
- AVA集合可以存储和操作数目不固定的一组数据。
- JAVA集合只能存放引用类型的的数据,不能存放基本数据类型;数组可以。
数组和集合的定义方法
-
数组(Array)
-
数组第一种定义方式
//分配长度为 4 个 int 型的内存空间,并分别赋初始值1,2,3,4
int[] array = new int[]{1, 2, 3, 4}; -
数组第二种定义方式
//方式一的简写
int[] array = {1, 2, 3, 4}; -
数组创建第三种方式(先初始化,后赋值)
//分配长度为 4 的内存空间,并全部赋为默认值 0
//相当于 int[] array = new int[4]{0, 0, 0, 0} 的简写
int[] array = new int[4];
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[0] = 1000; //在索引范围以内可以更改
-
-
集合
-
List
集合-
List集合包括List接口以及List接口的所有实现类。List集合具有以下特点:
- 集合中的元素允许重复
- 集合中的元素是有顺序的,各元素插入的顺序就是各元素的顺序
- 集合中的元素可以通过索引来访问或者设置
-
List接口的实现类:
- ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全)
- LinkedList:双向链表实现,增删快,查询慢 (线程不安全)
- Vector:数组实现,重量级 (线程安全、使用少)
-
创建事例
List<String> strList = new ArrayList<>();
strList.add("a");
strList.add("b");
strList.add("c"); -
List常用方法
void add(int index, Object element)
:添加对象element到位置index上boolean addAll(int index, Collection collection)
:在index位置后添加容器collection中所有的元素Object get(int index)
:取出下标为index的位置的元素int indexOf(Object element)
:查找对象element 在List中第一次出现的位置int lastIndexOf(Object element)
:查找对象element 在List中最后出现的位置Object remove(int index)
:删除index位置上的元素ListIterator listIterator(int startIndex)
:返回一个ListIterator 跌代器,开始位置为startIndexList subList(int fromIndex, int toIndex)
:返回一个子列表List ,元素存放为从 fromIndex 到toIndex之前的一个元素
-
-
Map
集合-
Map集合具有以下特点
- Map接口并没有继承Collection接口,提供的是key到value的映射
- Map中不能包含相同的key
-
Map接口的实现类
- HashMap:键值对,key不能重复,但是value可以重复;key的实现就是HashSet;value对应着放;允许null的键或值;
- Hashtable:线程安全的,不允许null的键或值;
- Properties::key和value都是String类型,用来读配置文件;
- TreeMap:对key排好序的Map; key 就是TreeSet, value对应每个key; key要实现Comparable接口或TreeMap有自己的构造器;
- LinkedHashMap: 此实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。存储的数据是有序的。
-
Map集合比较
- HashMap的存入顺序和输出顺序无关。
- LinkedHashMap 则保留了键值对的存入顺序。
- TreeMap则是对Map中的元素进行排序。
- 因为HashMap和LinkedHashMap 存储数据的速度比直接使用TreeMap 要快,存取效率要高。
- 当完成了所有的元素的存放后,我们再对整个的Map中的元素进行排序。这样可以提高整个程序的运行的效率,缩短执行时间。
注意:TreeMap中是根据键(Key)进行排序的。而如果我们要使用TreeMap来进行正常的排序的话,Key 中存放的对象必须实现Comparable 接口。
-
Map常用方法
Object put(Object key,Object value)
:用来存放一个键-值对Map中Object remove(Object key)
:根据key(键),移除键-值对,并将值返回void putAll(Map mapping)
:将另外一个Map中的元素存入当前的Map中void clear()
:清空当前Map中的元素Object get(Object key)
:根据key(键)取得对应的值boolean containsKey(Object key)
:判断Map中是否存在某键(key)boolean containsValue(Object value)
:判断Map中是否存在某值(value)public Set keySet()
:返回所有的键(key),并使用Set容器存放public Collection values()
:返回所有的值(Value),并使用Collection存放public Set entrySet()
:返回一个实现 Map.Entry 接口的元素 Set
-
-
Set
集合-
Set集合具有以下特点
- 集合中不包含重复元素(你可以重复添加,但只会保留第1个)
- 集合中的元素不一定保证有序
-
Set接口的实现类
HashSet
:equals返回true,hashCode返回相同的整数;哈希表;存储的数据是无序的。- HashSet的特征
- 不仅不能保证元素插入的顺序,而且在元素在以后的顺序中也可能变化(这是由HashSet按HashCode存储对象(元素)决定的,对象变化则可能导致HashCode变化
- HashSet是线程非安全的
- HashSet元素值可以为NULL
- HashSet常用方法
public boolean contains(Object o)
:如果set包含指定元素,返回truepublic Iterator iterator()
:返回set中元素的迭代器public Object[] toArray()
:返回包含set中所有元素的数组public Object[] toArray(Object[] a) :返回包含set中所有元素的数组,返回数组的运行时类型是指定数组的运行时类型public boolean add(Object o)
:如果set中不存在指定元素,则向set加入public boolean remove(Object o)
:如果set中存在指定元素,则从set中删除public boolean removeAll(Collection c)
:如果set包含指定集合,则从set中删除指定集合的所有元素public boolean containsAll(Collection c)
:如果set包含指定集合的所有元素,返回true。如果指定集合也是一个set,只有是当前set的子集时,方法返回true
- HashSet的特征
LinkedHashSet
:此实现与HashSet的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。存储的数据是有序的。TreeSet
:TreeSet实现了SortedSet接口,顾名思义这是一种排序的Set集合,查看jdk源码发现底层是用TreeMap实现的,本质上是一个红黑树原理。 正因为它是排序了的,所以相对HashSet来说,TreeSet提供了一些额外的按排序位置访问元素的方法,例如first(), last(), lower(), higher(), subSet(), headSet(), tailSet().EnumSet
:顾名思义就是专为枚举类型设计的集合,因此集合元素必须是枚举类型,否则会抛出异常。 EnumSet集合也是有序的,其顺序就是Enum类内元素定义的顺序。 EnumSet存取的速度非常快,批量操作的速度也很快。EnumSet主要提供以下方法,allOf, complementOf, copyOf, noneOf, of, range等。注意到EnumSet并没有提供任何构造函数,要创建一个EnumSet集合对象,只需要调用allOf等方法
-
-
各种Set集合性能分析
- HashSet和TreeSet是Set集合中用得最多的I集合。HashSet总是比TreeSet集合性能好,因为HashSet不需要额维护元素的顺序。
- LinkedHashSet需要用额外的链表维护元素的插入顺序,因此在插入时性能比HashSet低,但在迭代访问(遍历)时性能更高。因为插入的时候即要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素。
- EnumSet元素是所有Set元素中性能最好的,但是它只能保存Enum类型的元素
-
数组和集合的遍历方法
-
数组的遍历
- for 形式
for(int i=0;i<in1.length;i++){
for(int j=0;j<in1[i].length;j++){
System.out.println(in1[i][j]);
}
} - 增强for
int[][]in1={{1,2,3},{4},{5,6},{7,8,9,10}};
for(int [] k:in1){
for(int l:k){
System.out.println(l);
}
} - while形式
int i=0;
while(i<in1.length){
int j=0;
while(j<in1[i].length){
System.out.println(in1[i][j]);
j++;
}
i++;
} - do…while形式
int i=0;
do{
int j=0;
do{
System.out.println(in1[i][j]);
j++;
}while(j<in1[i].length);
i++;
}while(i<in1.length);
- for 形式
-
集合的遍历
-
List遍历
- 第一种遍历方法
for (String str : list) {
System.out.println(str);
} - 第二种遍历方法
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
```
* 第三种遍历方法
```java
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
- 第一种遍历方法
-
Map遍历
- 增强for循环
for(Obj o:c){
syso(o)
} - 使用iterator , Iterator it=c.iterator;
while(it.hasNext()){
Object o = it.next()
} - 普通循环
for(Iterator it=c.iterator();it.hasNext();){
it.next()
}
- 增强for循环
-
Set遍历
- 迭代遍历
Set<String> set = new HashSet<String>();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
} - for循环遍历
Set<String> set = new HashSet<String>();
for (String str : set) {
System.out.println(str);
} - set.forEach循环遍历(java8 才支持)
Set<String> set = new HashSet<String>();
set.forEach(item -> {
System.out.println(item);
}); - set.stream().forEach循环遍历(java8 才支持)
Set<String> set = new HashSet<String>();
set.stream().forEach(item -> {
System.out.println(item);
});
- 迭代遍历
-