数组
数组
数组的定义
定义: 存储同一种数据类型的多个数据,数组是引用数据类型
定义方式:动态初始化,静态初始化
定义格式
- 格式1: 数据类型[] 数组名;
- 格式2: 数据类型 数组名[];
数组的初始化
初始化:为数组中的数组元素分配内存空间,并为每个数组元素赋值。
Java中的数组必须先初始化,然后才能使用。
初始化的分类:
动态初始化: 只指定长度,由系统给出初始化值
格式:数据类型[] 数组名 = new 数据类型[数组长度];
数组长度其实就是数组中元素的个数。
静态初始化:给出初始化值,由系统决定长度
格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
简化格式:数据类型[] 数组名 = {元素1,元素2,…};
注意: 这两种方式,只能使用一种,不能进行动静结合
异常情况
ArrayIndexOutOfBoundsException:数组索引越界异常(原因:你访问了不存在的索引。)
NullPointerException:空指针异常(原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。)
二维数组
本质:二维数组其实就是每一个元素为一维数组的数组。
格式
格式1:数据类型[][] 变量名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组 必须写上
n表示每一个一维数组的元素个数 可选
格式2:数据类型[][] 变量名 = new 数据类型[m][];
m表示这个二维数组有多少个一维数组
这一次没有直接给出一维数组的元素个数,可以动态的给出。
**格式3:**数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}…};
简化版:数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
这个格式属于静态初始化:由我们指定具体的元素值,由系统给分配长度
不推荐使用的格式:数据类型 数组名[][] = new 数据类型[m][n];
数据类型[] 数组名[] = new 数据类型[m][n];
定义方式
动态初始化 int[][] mingzi = new int[3][2]
int[][] mingzi = new[3][]
静态初始化 int[][] arr = new int[][]{{1,1,1,1},{},{},{},{}}
int[][] arr={{1,1,1,1},{},{},{},{}}
二维数组下层的一维数组长度可自动扩充;
二维数组第一层为地址,指向第二层首地址;
二维数组的遍历:两层for循环
数组长度过大会造成堆内存溢出
代码解释
public class Array {
public static void main(String[] args) {
//创建数组
int[] arr1 = new int[2];
int[][]arr2 = new int[3][];
System.out.println(arr2);//二维数组的地址值
System.out.println(arr2[0]);//二维数组中第一个一维数组的地址值
System.out.println(arr2.length);//二维数组的长度
System.out.println(arr2[0].length);//第一个一维数组的长度
System.out.println(arr2[0][1]);//第一个一维数组第二个元素的值
集合
数组和集合的区别:
数组长度固定,集合长度可变;
数组可以存基本类型和引用类型,集合只有引用类型;
数组只有一种,集合可以混合存储
Collection接口
定义:容器,方便操作
成员方法
添加
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):添加一个集合的元素, 合二为一
删除
void clear():移除所有元素
boolean remove(Object o):移除一个元素
boolean removeAll(Collection c): a.Removeall(b);删除交集元素,对比b删除a, 没有执行删除操作时返回false、移除一个以上返回的就是true
判断
boolean contains(Object o):判断集合中是否包含指定的元素
boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含 才返回true)
boolean isEmpty():判断集合是否为空
获取
Size();长度
Retainsall();取交集
遍历集合:toArray() 把一个集合转成数组;其实就是依次获取集合中的每一个元素。
迭代器Iterator iterator()
List接口
List集合特点:元素有序,允许重复
子类
arraylist----底层数据结构—数组—线程不安全,效率高
Vector----底层数据结构—数组—线程安全,效率低
Linkedlist—底层数据结构—链表
成员方法
add(index,元素);指定位置加入指定元素
Get(index);获取指定位置元素;
Listinterator();迭代器,正在遍历集合时,只能使用迭代器自己的方法增删改添
Previous();前一个,迭代器指针不能再默认位置
Indexof(元素);第一次出现的索引
Lastindexof();最后一次位置索引
Remove(元素,装箱);删除指定元素
Remove(索引);删除指定位置元素
Set(index,元素);指定位置制定修改
Sublist();截取元素
ListIterator 继承自Iterator 可以使用Iterator中的方法
boolean hasPrevious():是否存在前一个元素
E previous():返回列表中的前一个元素
以上两个方法可以实现反向遍历 但是注意 要完成反向遍历之前 要先进行正向遍历 这样指针才能移到最后;如果直接反向遍历是没有效果的 因为指针默认位置就在最前面 他前面没有元素。
ConcurrentModificationException出现
我们用Iterator这个迭代器遍历采用hasNext方法和next方法,集合修改集合 会出现并发修改异常
原因是我们的迭代依赖与集合 当我们往集合中添加好了元素之后 获取迭代器 那么迭代器已经知道了集合的元素个数, 这个时候你在遍历的时候又突然想给 集合里面加一个元素(用的是集合的add方法) 那迭代器不同意 就报错了
解决方案 我们用ListIterator迭代器遍历 用迭代器自带的add方法添加元素 那就不会报错了
解决方案2 使用for循环遍历集合 添加元素 不会报错
迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
集合遍历元素,集合修改元素
Arraylist
特点:底层数据结构是数组,查询快,增删慢。线程不安全,效率高。
Comparator();排序
forEach();
vector
Vector 类可以实现可增长的对象数组 , Vector 是同步的。
特点:底层数据结构是数组,查询快,增删慢。线程安全,效率低。
addElement();添加元素
elementAt();获取
elements();遍历
firstElement();lastElement();
removeAllElement();清空
linkedlist
特点:底层数据结构是链表,查询慢,增删快。线程不安全,效率高。
addFirst();addLast();getFirst();getLast();removeFirst();removeLast()
poll();获取并删除链头;
peek();获取表头
set接口
特点:元素无序,且不重复
Hashset
特点:底层数据结构哈希表
元素无序且唯一(唯一性由元素重写hashcode();equals();来实现)
默认初始容量16;加载因子0.75
可以为null
线程不安全
链表的数组,结合了数组和链表的优点(优化+红黑树)
结论:HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
LinkedHashSet
特点:有两个 链表和哈希表 、 链表保证有序 哈希表保证元素唯一
treeSet
特点: 元素唯一,并且可以对元素进行排序(自然排序、比较器排序)
注意:使用TreeSet集合进行元素的自然排序,那么对元素有要求,要求这个元素 必须实现Comparable接口 否则无法进行自然排序, 保证元素的唯一性是靠compareTo方法的返回值来确定如果返回0 表示两个元素相等,则不重复存储
map集合
概述:存储键值映射关系的数据(主要是键)
特点:一个键映射一个值,键相同时会覆盖值
允许null值、键
成员方法:
添加: V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
删除: void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
判断: boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
获取: Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set keySet():获取集合中所有键的集合
Collection values():获取集合中所有值的集合
长度: int size():返回集合中的键值对的对数
键找值思路:获取所有键的集合遍历键的集合,获取到每一个键根据键找值
键值对对象找键和值思路:获取所有键值对对象的集合遍历键值对对象的集合,获取到每一个键值对对象根据键值对对象找键和值
hashMap
特点:允许插入null键 null值
成员方法:put();添加元素
Clear();清空集合
Remove();删除指定
Containskey();containsvalue();isempty();判断
hashTable
类似hashmap
区别:m线程不安全,效率高,允许null
T线程安全,效率低,不允许null
kinkedHashMap
特点:可预知的迭代顺序
底层数据结构链表和哈希表
元素有序且唯一,元素的有序性由链表数据结构保证 唯一性由 哈希表数据结构保证
Map集合的数据结构只和键有关
treeMap
特点:键的数据结构是红黑树,可保证键的排序和唯一性
不允许插入null
键对象需要实现comparetable接口
排序分为自然排序和比较器排序
线程是不安全的效率比较高
properties
属性集合:键值都是字符串类型
Properties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载。
Properties父类是Hashtable
属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型
成员方法:
存数据:setproperty(键,值);
取数据:getproperty(键);重载B计划(由键未找到值时,会加载默认值)
存数据到文件:public void load(Reader reader);
读取数据从文件:public void store(Writer writer, String comments);
Map集合的遍历
Size();获取长度
方式1:获取所有键keyset();由键找值getkey();循环输出for();
获取所有值valus();
方式2:entryset();(返回键值对对象–node)循环输出键值对
集合工具类
Collections 提供针对集合操作 的工具类
成员方法:public static void sort(List list);排序(自然顺序)
public static int binarySearch(List<?> list,T key);二分查找
public static T max(Collection<?> coll);获取最大值
public static void reverse(List<?> list);反转
public static void shuffle(List<?> list);打乱顺序