数组
1、什么是数组
数组是存储长度固定的容器,存储多个数据的数据类型要一致
格式:数据类型[ ] 数组名;
如:int[ ] arr;
2、数组动态初始化:
如:int[ ] arr = new int[5]; 该数组默认初始化长度为5,且每一个值为0;
如:int[ ] arr = {1,2,3,4,5}; 该数组初始化了数值;
3、数组元素的访问
格式:数组名[索引]; arr[i]
数组的索引从0开始;
数组的长度:arr.length
获取每一个数组只需要遍历即可:
for (int i = 0; i < arr.length; i++) {
if (arr[i]==null){
System.out.println( arr[i]);
}
数组的增删改查
增:每一个索引arr[i]对应一个值;
删:将对应索引arr[i]=null覆盖即可;
改:将对应索引arr[i]=值覆盖即可;
查:遍历数组,与对应索引i的arr[i]相等(equals)即可;
4、冒泡排序
int[] arr = {5,4,7,3,9,2};
for (int i = 0; i < arr.length-1; i++) { //此处遍历数组次数(轮数)比数组的长度要少一次
for (int j = 0; j < arr.length - i - 1; j++) { //内存循环就是实际比较,此处遍历数组每一轮的个数:长度要减去轮数和最大值 //-1:是指为了让数组不越界 -i:是指每一轮结束后我们少比一个数字
if (arr[j]>arr[j+1]){ //前一个值对比后一个值,是否比它大
int tem=arr[j+1]; //满足条件则,现将后一个值存起来
arr[j+1]=arr[j]; //将前一个值赋值给后一个值
arr[j]=tem; //将原来后一个值赋值给前一个值,达到小的排前,大的排后的效果
}
}
}
for (int z = 0; z < arr.length; z++) { //遍历数组
System.out.println(arr[z]);
}
5、数组操作的两个常见小问题
1、ArrayIndexOutOfBoundsException 数组越界异常
数组索引为数组的长度-1(arr.length-1),从0开始;
2、NullPointerException 空指针异常
数组没有值为null时出现空指针异常 或者 new arr[5]当你用arr[i]调用方法时arr[i].getId(),也会出现空指针,因为arr[i]初始化值为0,0怎么调用方法所以报错。
集合
1、ArrayList集合
ArrayList 是 java 集合框架中比较常用的数据结构。继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。同时还实现了 RandomAccess、Cloneable、Serializable 接口,所以ArrayList 是支持快速访问、复制、序列化的。
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。ArrayList 底层基于数组实现容量大小动态可变。 扩容机制为首先扩容为原始容量的 1.5 倍。初始默认值是10。
1、ArrayList继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
2、ArrayList实现了RandmoAccess接口,即提供了随机访问的功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
3、ArrayList实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
4、ArrayList实现了java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
注意:ArrayList中的操作不是线程安全的!所以,建议在单线程中使用,多线程情况下可以选择CopyOnWriteArrayList或者使用Collections中的synchronizedList方法将其包装成一个线程安全的List。
// Collection中定义的API
boolean add(E object)
boolean addAll(Collection<? extends E> collection)
void clear()
boolean contains(Object object)
boolean containsAll(Collection<?> collection)
boolean equals(Object object)
int hashCode()
boolean isEmpty()
Iterator<E> iterator()
boolean remove(Object object)
boolean removeAll(Collection<?> collection)
boolean retainAll(Collection<?> collection)
int size()
<T> T[] toArray(T[] array)
Object[] toArray()
// AbstractCollection中定义的API
void add(int location, E object)
boolean addAll(int location, Collection<? extends E> collection)
E get(int location)
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator<E> listIterator(int location)
ListIterator<E> listIterator()
E remove(int location)
E set(int location, E object)
List<E> subList(int start, int end)
// ArrayList新增的API
Object clone()
void ensureCapacity(int minimumCapacity)
void trimToSize()
void removeRange(int fromIndex, int toIndex)
2、集合的增删改查
增:add()可添加对象到集合。或根据索引,元素添加达到插队的效果。
删:remove()可根据索引元素移除,也可根据元素移除,但没移除一个元素,后面的元素会前移一位,所以在批量移除时需要做i–操作。
改:set()传入两个参数,一个是索引,一个是新修改的元素或对象。
查:get()根据索引获取元素。
3、ArrayList源码
//序列化id
private static final long serialVersionUID = 8683452581122892189L;
//容器默认初始化大小
private static final int DEFAULT_CAPACITY = 10;
//一个空对象
private static final Object[] EMPTY_ELEMENTDATA = {};
//一个空对象,如果使用默认构造函数创建ArrayList,则默认对象内容是该值
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//ArrayList存放对象的容器,后面的添加、删除等操作都是基于该属性来进行操作
transient Object[] elementData;
//当前列表已使用的长度
private int size;
//数组最大长度(2147483639),这里为什么是Integer.MAX_VALUE - 8是因为有些虚拟机在数组中保留了一些头部信息,防止内存溢出
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//这个是从AbstractList继承过来的,代表ArrayList集合修改的次数
protected transient int modCount = 0;
static关键字
static关键字是一个修饰符,用于修饰类的成员方法和成员变量;被static修饰的方法和变量在类加载时就被创建了。并被所有类共享。皆可访问。
1、修饰成员方法
被称为静态方法,可以直接通过类名调用,因为该方法在类加载时就被创建所以还未等到对象new出来就有了,所以它不依附于对象。
既然不依附于对象,所以也没有this。
静态方法不能访问非静态方法和变量,因为静态方法被创建时,非静态方法还不一定创建出来了。但非静态方法能够访问静态方法和变量。
2. static修饰成员变量
static修饰的变量也称为静态变量,静态变量和非静态变量的区别是:静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。
3、static修饰代码块
static关键字还有一个比较重要的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来依次执行每个static块,并且只会执行一次。 static块可以优化程序性能,是因为它的特性:只会在类被初次加载的时候执行一次。