java中的常量
1、对于java中的常量名称规则:所有的单词字母都是大写,如果有多个字母,那么使用下划线连接。
2、在java中声明final常量的时候通常都会加上static关键字,这样对象的每个实例都会访问唯一的一份常量值。
原因是因为:如果不加static直接使用final修饰的话,每个对象里面的值都会有这个常量,这个常量是不能改变的。如果加了static,则所有对象共享这个常量,这个常量也是不能改变的,加上static更好维护。
IDE
IDE(Integrated Development Environment),集成开发环境。
比如Eclipse、Intellij IDEA等等
集合
3、 集合:集合是整个java中最重要的一部分,集合是建立在数组之上以及对后面开发有很大影响。
一、标题ArrayList(数组列表)
标题ArrayList底层是用数组实现的存储
(1)、ArrayList的特点
查询效率高,删除效率低,线程不安全,使用频率高。
(2)、ArrayList的六大问题
1、查询效率高?
ArrayList是顺序结构,只要知道存储的首地址以及各个大数据元素所占单元,就可以计算出各元素的存储地址。
2、删除效率低?
取决于你要删除的元素离数组末端有多远,ArrayList拿来做堆栈来用还是挺合适的,push和pop操作不涉及数据移动操作。。
3、线程不安全?
当然是不安全的,线程安全的版本的数组容器为Vector,Vector的实现很简单,就是把所有的方法就加上synchronized。
4、为什么线程不安全,它使用频率还高?
因为在我们正常使用场景中,一般都是查询,很少有频繁的增删,如果涉及频繁的增删,可以使用LinkedList。
5、ArrayList如何扩容?
ArrayList的默认大小为10(没找到什么具体原因,估计长度为10最常用,最有效率)。ArrayList可以通过构造方法在初始化的时候指定底层数组的大小。
源码中可以看出通过无参构造方法初始化ArrayList(),则赋值为一个默认空的数组,所有容量为0,只有真正对数据进行add时,才分配默认的大小为10.数组的长度有限制,ArrayList可以存放任意数量对象,通过数组扩容,扩容后的大小 等于扩容前大小的1.5倍。 把原数组的数据原封不动的复制到新数组。
/** * 要分配的最大数组大小 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/** * ArrayList扩容的核心方法。 */
private void grow(int minCapacity) {
// oldCapacity为旧容量,newCapacity为新容量
int oldCapacity = elementData.length;
//将oldCapacity 右移一位,其效果相当于oldCapacity /2,
//我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍,
int newCapacity = oldCapacity + (oldCapacity >> 1);
//然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) `hugeCapacity()` 方法来比较 minCapacity 和 MAX_ARRAY_SIZE,
//如果minCapacity大于最大容量,则新容量则为`Integer.MAX_VALUE`,否则,新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8`。
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
将oldCapacity 右移一位,其效果相当于oldCapacity /2,我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍, int newCapacity = oldCapacity + (oldCapacity >> 1);
看System.arraycopy方法将原数组的内容拷贝到扩容的新数组中:
import java.util.Arrays;
/**
*
* @author xinbai
* 2020-4-17,下午8:46:54
*/
public class Demo3ArrayList {
public static void main(String[] args) {
int [] arr={1,2,3};
int [] brr=new int[10];
System.arraycopy(arr, 0, brr, 0, arr.length);
System.out.println(Arrays.toString(brr));
}
}
Arrays.copyof()方法给原数组扩容:
import java.util.Arrays;
/**
*
* @author xinbai
* 2020-4-17,下午8:46:54
*/
public class Demo3ArrayList {
public static void main(String[] args) {
int [] arr={1,2,3};
int [] brr=Arrays.copyOf(arr, 10);
System.out.println(brr.length);
System.out.println(Arrays.toString(brr));
}
}
6、数组用来做队列合适吗?
队列一般是FIFO的,如果用ArrayList做队列,就需要在数组尾部追加数据,数组头部删除数组,反过来也可以。但是无论如何总会有一个操作会涉及到数组的数据搬迁,这个是比较耗费性能的。这个回答是错误的!ArrayList固然不适合做队列,但是数组是非常合适的。
二、LinkedList
LinkedList是基于双向列表来实现,利于插入,删除,仅需修改数据元素的指针字段值,而不必移动数据元素。
LinkedList的时间复杂度为O(N),ArrayList不考虑底层数组自动扩容的话,时间复杂度为O(1),在指定位置添加元素,根据最坏打算,时间复杂度是O(n)。
LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
ArrayList适合查找,LinkedList适合增删。
三、List
集合中的List这个接口主要由两个实现类,一个是实现类是ArrayList[数组列表],另外一个LinkedList实现类[链接列表或者交列表],这两个类都实现了List的这个接口,所以它们的方法有很多共通的地方。