Java数组
数组概念
数组定义:相同类型数据的有序集合
数组的四个特点:
- 长度确定。数组一旦被创建,大小就是不可以改变的
- 其他元素的类型必须是相同类型,不允许出现混合类型。
- 数组类型可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也是对象,数组中的元素相当于对象的属性。
数组声明方式:(一维数组)
type[] arr_name; // 方式1
type arr_name[]; // 方式2
注:
- 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关
- 声明一个数组的时候并没有数组真正被创建
- 构造一个数组,必须指定长度
例:
public class arr {
public static void main(String args[]) {
int[] ar; // 声明数组
ar = new int[10]; // 给数组分配空间
for (int i = 0; i < 10; i++) {
ar[i] = 2 * i + 1;
System.out.println(ar[i]);
}
}
}
三种初始化方式
静态初始化:
除了用new关键字类产生数组以外,还可以直接在定义的数组的同时就为数组元素分配空间并赋值
int[] arr = {1, 2, 3, 4};
student[] stu1 = {new student(1,18), new student(2,22)};
动态初始化:
通过下标访问赋值。
默认初始化:
数组也是对象,它的元素相当于对象的属性,每个元素也按照属性的方式被默认初始化。
int a[] = new int[2]; // 默认值:0, 0
boolean[] b = new boolean[2]; // 默认值:false, false
String[] s = new String[2]; // 默认值:null, null
数组的常见操作
普通遍历:
通过循环下标访问。
for-each 遍历:
for-each 专门用于读取数组或容器中所有的元素,即数组进行遍历。
int[] a = {1, 2, 3, 4};
for (int temp:a) {
System.out.println(temp);
}
注:
- for-each 增强for循环在遍历数组过程中不能修改数组中某些元素的值。
- for-each 仅适用于遍历,不涉及有关索引(下标)的操作。
java.util.Array类用法
Arrays类包含了:排序、查找、填充、打印内容等常见的数组操作。
System.out.println(Arrays.toString(a)); // 打印数组a元素的值
Arrays.sort(a); // 对数组元素排序,由小到大
// 使用二分法查找,必须先对数组进行排序;
System.out.println("该元素的索引:"+Arrays.binarySearch(a, 12));// 返回排序后新的索引位置,若未找到返回负数
Arrays.fill(a, 2, 4, 100); // 将2到4索引的元素替换为100
拷贝:
System.arraycopy(object src, int srcpos, object dest, int destpos, int length)
src:源数组
srcpos:源数组中的起始位置
dest:目标数组
destpos:目标数据中的起始位置
length:要复制的数组元素的数量
多维数组
多维数组内存结构:
多维数组可以看成以数组为元素的数组。
Java中多维数组的声明和初始化应按从低维到高维的顺序进行
int[][] a = new int[3][];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];
// int a1[][] = new int[][4]; // 非法
int[][] b = {
{1, 2, 3},
{5, 6},
{0, 8, 7}
}; // 静态初始化
int[][] c = new int[3][];
c[0] = new int[]{1, 2};
c[1] = new int[]{3, 4};
c[2] = new int[]{5, 6, 7};
多维数组存储表格:
表格是计算机世界最普遍的模型。
Object[] a1 = {1001, "张三", 22, "教师"};
Object[] a2 = {1002, "小王", 18, "学生"};
Object[] a2 = {1003, "老王", 30, "教师"};
Object[][] temp = new Object[3][];
temp[0] = a1;
temp[1] = a2;
temp[2] = a3;
Javabean和数组存储表格:
使用javabean和数组保存表格信息。
public class sheet {
public statci void main(String[] args) {
temp[] temps = {
new temp(1001, "老王", 38),
new temp(1002, "张三", 20),
new temp(1003, "李四", 23)
};
// 遍历
for (temp a:temps) {
System.out.println(e);
}
}
}
class temp {
private int id;
private String name;
private int age;
// 重写toString
public String toString() {
return "temp{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age + '}';
}
public temp(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
常见算法
Comparable接口(定义比较策略)
多个对象做比较,就要有“比较规则”,然后实现排序。
事实上,java中排序算法的底层也依赖Comparable接口。
Comparable接口中只有一个方法:
public int comparaTo(Object obj) obj为要比较的对象
方法中,将当对象和obj这个对象进行比较,如果大于返回1,等于返回0,小于返回-1.compareTo方法的代码也比较固定:
public int comparaTo(Object o) {
Student stu = (Student)o;
if(this.age < Student.age) {
return -1;
}
if(this.age > Student.age) {
return 1;
}
return 0;
}
实例代码:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Student[] stu = {new Student(3,"A"),
new Student(60, "B"),
new Student(2, "C")};
Arrays.sort(stu);
System.out.println(Array.toString(stu));
}
}
class Student implements Comparable {
int age;
int id;
String name;
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public String toString() {
return this.name;
}
public int compareTo(Object o) {
Student man = (Student)o;
if (this.age < Student.age) {
return -1;
}
if (this.age > Student.age) {
return 1;
}
return 0;
}
}
冒泡排序基础算法
public void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
冒泡排序优化算法
public void optimizedBubbleSort(int[] arr) {
int n = arr.length;
boolean flag;
for (int i = 0; i < n - 1; i++) {
flag = false;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true;
}
}
// 如果一次内循环中没有发生交换,表示数组已经有序,可以提前结束排序
if (!flag) {
break;
}
}
}
二分法查找
二分法查找又称折半查找。
代码实例:
public class BinarySearch {
public static int binarySearch(int[] array, int target) {
int low = 0;
int high = array.length - 1;
while (low <= high){
int mid = (low + high) / 2;
if (array[mid] == target){
return mid; // 目标值找到,返回索引位置
}
else if (array[mid] < target){
low = mid + 1; // 目标值在右半部分,舍弃左半部分
}
else{
high = mid - 1; // 目标值在左半部分,舍弃右半部分
}
}
return -1; // 目标值未找到,返回 -1
}
public static void main(String[] args) {
int[] array = {2, 5, 7, 12, 18, 20, 24, 30};
int target = 12;
int resultIndex = binarySearch(array, target);
if (resultIndex != -1){
System.out.println("目标值 " + target + " 的索引位置为 " + resultIndex);
}
else{
System.out.println("目标值 " + target + " 未找到");
}
}
}
此示例中,通过调用 binarySearch 方法来实现二分查找。如果找到目标值,则返回其索引位置,否则返回 -1。
如果数组并不是有序的,必须在调用二分法查找方法前使用排序使其有序。