1.数组
1.1 一维数组
1.1.1一维数组的声明
int[] arrayName //(建议)
或
int arrayName[]
1.1.2 一维数组的创建
int[] arrayName;
arrayName=new int[3];
或者
int arrayName[]=new int[3];
1.1.3 一维数组的初始化
int[] arrayName={1,2,3,4,5};
或者
float arrayName[]=new int[5];
arrayName[0]=1.2f;
arrayName[1]=3.4f;
arrayName[2]=4.5f;
arrayName[3]=7.9f;
arrayName[4]=7.9f;
1.1.4一维数组的默认值
数据结构 | 数组元素的默认值 |
---|---|
byte,short,int long | 0 |
float,double | 0.0 |
char | ‘\0’(空格) |
boolean | false |
object type | null |
1.2 二维数组
1.2.1 二维数组的声明
int[][] intarrayName; //建议
或
int intarrayName[][];
1.2.2二维数组的创建
方式1:
int[][] num=new int[3][4];
String[][] userName=new String[2][2]
方式2:
int[][] arrayName=new int[3][];
arrayName[0]=new int[3];
arrayName[1]=new int[2];
arrayName[2]=new int[4];
错误方式
int [][] arrayName=new int[][3];
int [][] arrayName=new int[][];
1.2.3 二维数组的初始化
//第一种方式:
int a[][]={{1,2,3},{4,5,6}};
//第二种方式;
int[][] ints = new int[4][2];
ints[i][j] =__; //分别赋值
//第三种方式:第二维的长度可以动态申请
int[][] arr3 = new int[5][];//五行的长度
for(int i=0; i<arr3.length; ++i){
arr3[i]=new int[i+1]; //列的长度每次都变化。每次都要重新申请空间(长度)
for(int j=0; j<arr3[i].length; ++j)
arr3[i][j]= i+j;
1.3数组的相关操作
1.3.1 数组长度
数组长度指的是数组的大小,即数组包含元素的个数。
语法如下:
arrayName.length //返回数组的长度
1.3.2 数组填充
指的是将一个数组或数组指定元素用固定值添加到数组中。
Arrays.fill(arrayName,value);
或
Array.fill(arrayName,startIndex,endIndex,value);
1.3.3 数组复制
数组复制就是将一个指定范围内的元素复制到另一个数组中去
语法格式
ArrayCopy(originalArray,originalIndex,targetArray,targetIndex,copyLength);
1.3.4 数组比较
如果两个数组长度一样,并且相同位置的元素也一样,那么这两个数组相等,否则,不相等。
Arrays.equals(array1,array2);
返回值为boolean值。
1.3.5 数组排序
数组排序主要是sort函数排序
Arrays.sort(array);
或
Arrays.sort(array,startIndex,endIndex);
2.集合
2.1集合接口
参考文章 https://www.cnblogs.com/chenglc/p/8073049.html
Collection和Map,是集合框架的根接口。
Collection的子接口:
Set:接口 —实现类: HashSet、LinkedHashSet
Set的子接口SortedSet接口—实现类:TreeSet
List:接口—实现类: LinkedList,Vector,ArrayList
接口 | 接口描述 |
---|---|
Collection接口 | Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。 |
List 接口 | List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。 |
Set接口 | Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。 |
SortedSet接口 | 继承于Set保存有序的集合。 |
Map接口 | Map 接口存储一组键值对象,提供key(键)到value(值)的映射。 |
Map.Entry | 描述在一个Map中的一个元素(键/值对)。是一个Map的内部类。 |
SortedMap | 继承于 Map,使 Key 保持在升序排列。 |
Enumeration | 这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。 |
Set接口和List接口的区别:
-
Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
-
Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
-
List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
2.2 集合实现类
2.2.1 List集合
有序列表,允许存放重复的元素;
实现类:
ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全)
LinkedList:双向链表实现,增删快,查询慢 (线程不安全)
Vector:数组实现,重量级 (线程安全、使用少)
2.2.1.1 ArrayList
底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。
2.2.1.2 LinkedList
LinkedList是采用双向循环链表实现的。
利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。
它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。
经常用在增删操作较多而查询操作很少的情况下:
队列和堆栈。
队列:先进先出的数据结构。
栈:后进先出的数据结构。
注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。
2.2.1.3 Vector
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。
2.1.1.4 List常用的方法
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 跌代器,开始位置为startIndex
List subList(int fromIndex, int toIndex) :返回一个子列表List ,元素存放为从 fromIndex 到toIndex之前的一个元素
2.2.2 Set集合
无序列表,不允许存放重复的元素;
2.2.2.1 HashSet类
HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构是哈希表。
哈希表
一个元素为链表的数组,综合了数组与链表的优点。
HashSet具有以下特点:
- 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也可能发生变化;
- HashSet不是同步的;
- 集合元素值可以是null;
内部存储机制
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较true,但它们的hashCode方法返回的值不相等,HashSet将会把它们存储在不同位置,依然可以添加成功。
也就是说。HashSet集合判断两个元素的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。
靠元素重写hashCode方法和equals方法来判断两个元素是否相等,如果相等则覆盖原来的元素,依此来确保元素的唯一性
2.2.2.2 LinkedHashSet类
HashSet还有一个子类LinkedList、LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的,也就是说当遍历集合LinkedHashSet集合里的元素时,集合将会按元素的添加顺序来访问集合里的元素。
输出集合里的元素时,元素顺序总是与添加顺序一致。但是LinkedHashSet依然是HashSet,因此它不允许集合重复。
2.2.2.3 TreeSet类
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态
内部存储机制
TreeSet内部实现的是红黑树,默认整形排序为从小到大。
2.2.2.4 EnumSet类
- EnumSet是一个专门为枚举类设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。EnumSet的集合元素也是有序的,EnumSet以* 枚举值在Enum类内的定义顺序来决定集合元素的顺序。
- EnumSet在内部以位向量的形式存储,这种存储形式非常紧凑、高效,因此EnumSet对象占用内存很小,而且运行效率很好。
- EnumSet集合不允许加入null元素。
EnumSet类没有暴露任何构造器来创建该类的实例,EnumSet类提供了以下类方法来创建EnumSet对象。
- EnumSet allOf(Class elementType):创建一个包含指定枚举类里所有枚举值的EnumSet集合。
- EnumSet complementOf(EnumSet s):创建一个其元素类型与指定EnumSet里元素类型相同的EnumSet集合,新的集合里包含原集合不包含的枚举值。
- EnumSet copyOf(Collection c):使用一个普通集合来创建EnumSet集合;
- EnumSet copyOf(EnumSet s):复制原集合;
- EnumSet noneOf(Class elementType):创建一个元素类型为指定枚举类型的空EnumSet;
- EnumSet of(E first,E…rest):创建一个包含一个或多个枚举值的EnumSet集合。传入的枚举值必须是同一枚举类。
- EnumSet range(E from,E to):创建一个包含从from到to枚举值范围所有枚举值的EnumSet集合。
实例代码:
package org.westos.demo9;
public enum SeasonEnum {
//在第一行列出4个枚举实例
Spring,Summer,Fall,Winter;
}
package org.westos.demo9;
import java.util.EnumSet;
public class EnumSetTest {
public static void main(String[] args) {
//创建一个EnumSet集合,集合元素是Season枚举类的全部枚举值
EnumSet<SeasonEnum> es1 = EnumSet.allOf(SeasonEnum.class);
System.out.println(es1);//[Spring, Summer, Fall, Winter]
//创建一个EnumSet空集合,元素类型为Season类的枚举值
EnumSet<SeasonEnum> es2 = EnumSet.noneOf(SeasonEnum.class);
System.out.println(es2);//[]
//手动添加两个元素
es2.add(SeasonEnum.Spring);
es2.add(SeasonEnum.Summer);
System.out.println(es2);//[Spring, Summer]
//以指定枚举值创建EnumSet结合
EnumSet<SeasonEnum> es3 = EnumSet.of(SeasonEnum.Spring, SeasonEnum.Fall);
System.out.println(es3);//[Spring, Fall]
EnumSet<SeasonEnum> es4 = EnumSet.range(SeasonEnum.Summer, SeasonEnum.Winter);
System.out.println(es4);//[Summer, Fall, Winter]
//输出es4中不包含的枚举值
EnumSet<SeasonEnum> es5 = EnumSet.complementOf(es4);
System.out.println(es5);//[Spring]
}
}
Collection c = new HashSet<>();
c.clear();
c.add(SeasonEnum.Spring);
c.add(SeasonEnum.Summer);
//复制集合中的元素来创建EnumSet
EnumSet enumSet = EnumSet.copyOf(c);
System.out.println(enumSet);//[Spring, Summer]
c.add("Monday");
c.add("ThusDay");
EnumSet enumSet1 = EnumSet.copyOf(c);
//出现ClassCastException异常,因为后面添加的两个元素不是枚举值