数组:
相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次 序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下 标)来访问它们。
数组的分类:
1.一维数组、二维数组、、、
2.按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
三个基本特点:
1.长度是确定的。数组一旦被创建,它的大小就是不可以改变的
2.其元素必须是相同类型,不允许出现混合类型
3.数组类型可以是任何数据类型,包括基本类型和引用类型
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量
1.声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与 长度有关
2.声明一个数组的时候并没有数组真正被创建
3.构造一个数组,必须指定长度
数组定义的语法格式:
数据类型[] 变量名字 = new 数据类型[容量];
int[] arr = new int[10];
=是赋值号:
=左边 :
数据类型:确定当前数组中保存的数据类型是哪一种。要求有且只能保存当前数据指定类型的数据。严格执行数据一致化的问题。
[]:1.确定当前创建的形式是数组。
2.确定数组是一个引用数据类型的。
=右边:
new: 创建数组的关键字。
数据类型:
[]:确定当前数组中的容量是多少
数组的初始化:
1.静态初始化
数组的初始化和数组元素的赋值操作同时进行
2.动态初始化
数组的初始化和数组元素的赋值操作分开进行
3.默认初始化
数组元素下标的合法区间:[0,length - 1]。
for-each:增强for循环是JDK1.5新增的功能,专门用于读取数组或集合中所有的元素,即对数组或集合进行遍历。
二维数组:
1.理解:对于二维数组的理解,我们可以看成是一维数组 array1 又作为另一个一维数组 array2的元素而存在。
从数组底层的运行机制来看,其实没有多维数组。
int[][] arr = new int[3][2];
数组中涉及的常见算法
1.数组元素的赋值(杨辉三角、回形数等)
2.求数值型数组中元素的最大值、最小值、平均数、总和等
3.数组的复制、反转、查找(线性查找、二分法查找)
4.数组元素的排序算法
数据结构:
1.数据与数据之间的逻辑关系:集合、一对一、一对多、多对多
2.数据的存储结构:
线性表:顺序表(比如:数组)、链表、栈、队列
**树形结构:**二叉树
图形结构:
数组的常用方法:
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组的各种方法。
1 | boolean equals(int[] a, int[] b) | 判断两个数组是否相等 |
---|---|---|
2 | Stirng toString(int[] a) | 输出数组信息 |
3 | void fill(int[] a, int val) | 将指定值填充到数组之中 |
4 | void sort(int[] a) | 对数组进行排序 |
5 | int binarySearch(int[] a, int key) | 对排序后的数组进行二分法检索指定的值 |
数组常见异常:
1.数组下标越界异常:ArrayIndexOutofBoundsExcetion
2.空指针异常:NullPointerException
算法:
算法的5大特征 | |
---|---|
输入(Input) | 有0个或多个输入数据,这些输入必须有清楚地描述和定义 |
输出(Output) | 至少有1个或多个输出结果,不可以没有输出结果 |
有穷性(有限性,Finiteness) | 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成 |
确定性(明确性,Definiteness) | 算法中的每一步都有确定的含义,不会出现二义性 |
可行性(有效性,Effectiveness) | 算法的每一步都是清楚可行的,能让用户用纸笔计算而求出答案 |
说明:满足确定性的算法也称为:确定性算法。现在人们也关注更广泛的概念,例如考虑各种非确定性的算法,如并行算法、概率算法等。另外,人们也关注并不要求终止的计算描述,这种描述有时被称为过程(procedure)。
排序算法:
排序的目的是为了快速查找。
衡量排序算法的优劣:
1.时间复杂度:分析关键字的比较次数和记录的移动次数
2.空间复杂度:分析排序算法中需要多少辅助内存
3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的
**排序算法分类:**内部排序和外部排序
内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成
**外部排序:**参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成
十大内部排序算法:
选择排序
直接选择排序、堆排序
交换排序
冒泡排序、快速排序
插入排序
直接插入排序、折半插入排序、Shell排序
归并排序
桶式排序
基数排序
搜索算法:
//数组的复制:
String[] arr = new String[]{"AA","BB","CC","DD"};
String[] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
//数组的反转
String[] arr = new String[]{"AA","BB","CC","DD"};
for (int i = 0; i < arr.length / 2; i++) {
String temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//线性查找
String[] arr = new String[]{"AA","BB","CC","DD"};
String dest = "BB";//指定的元素
boolean isFlag = true;
for (int i = 0; i < arr.length; i++) {
if(dest.equals(arr[i])) {
System.out.println("找到了指定的元素,位置为:" + i);
isFlag = false;
break;
}
}
if(isFlag) {
System.out.println("很遗憾,没有找到指定的元素");
}
//二分法查找 前提:所要查找的数组必须有序
int[] arr2 = new int[]{-88,-59,-18,-4,3,25,56,78,148,216};
int dest1 = -4;//指定的元素
int head = 0;//初始的索引
int end = arr2.length - 1;//初始的末索引
boolean isFlag1 = true;
while(head <= end) {
int middle = (head + end)/2;
if(dest1 == arr2[middle]) {
System.out.println("找到了指定的元素,位置为:" + middle);
isFlag1 = false;
break;
}else if(dest1 < arr2[middle]) {
end = middle - 1;
}else {
head = middle + 1;
}
}
if(isFlag1) {
System.out.println("很遗憾,没有找到指定元素!");
}
//冒泡排序
int[] arrM = new int[]{63,84,12,-33,-1,29,70,5};
for(int i = 0; i < arrM.length - 1; i++) {
for (int j = 0; j < arrM.length - 1 - i; j++) {
if(arrM[j] > arrM[j + 1]) {
int temp = arrM[j];
arrM[j] = arrM[j + 1];
arrM[j + 1] = temp;
}
}
}
for (int i = 0; i < arrM.length; i++) {
System.out.print(arrM[i] + "\t");
}
API文档使用
抽象方法:使用 abstract 修饰的方法,只有声明。
定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
抽象类:包含抽象方法的类就是抽象类。通过 abstract 方法定义规范,然后要求子类必须定义 具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用
抽象类的使用特点:
1.有抽象方法的类只能定义成抽象
2.抽象类不能实例化,即不能用 new 来实例化抽象类
3.抽象类可以包含属性、方法、构造方法。但是构造方法不能用来 new 实例,只能用来被子类 调用
4.抽象类只能用来被继承
5.抽象方法必须被子类实现
接口(interface):
1.访问修饰符:只能是 public 或默认
2.接口名:和类名采用相同命名机制
3.extends:接口可以多继承
4.常量:接口中的属性只能是常量,总是: public static final 修饰。不写也是
5.方法:接口中的方法只能是: public abstract 修饰。省略也是
要点:
1.子类通过implements来实现接口中的规范。
2.接口不能创建实例,但是可用于声明引用变量类型。
3.一个类实现了接口,就必须实现接口中所有的方法,并且这些方法必须是 public的
4.JDK 1.7 之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方 法
5.JDK 1.8 后,接口中包含普通的静态方法