数组
数组
数组定义
数组引入
如果说这 100 个整型变量都有相关性,那么请问,这个时候该如何统一的进行这 100 个变量的调用管理呢?难道说每一次的执行都要指明具体的变量么?那么现在为了解决这样的设计问题,所以才提出了关于数组的概念,所以使用数组最大的特点就是可以直接解决一组相关变量的定义与管理问题。
数组定义
Java 中的数组比较特殊一些,因为任何语言的数组实际上都会牵扯到内存的分配机制问题,所以在这样的环境下 Java 将数组归纳为引用数据类型,那么针对于数组的创建语法在 Java 里面支持有两类:
- 第一类:声明并开辟数组空间
- 数据类型[] 数组名称=new 数据类型[数组长度];
- 数据类型 数组名称 []= new 数据类型[数组长度];
- 第二类:先声明数组后再开辟数组空间
- 声明数组:
- 数据类型[] 数组名称 =nuI
- 数据类型 数组名称 []= null
- 开辟数组空间:
- 数组名称 = new 数据类型[数组长度]
- 声明数组:
范例
定义访问数组
public class Test {
public static void main(String[] args) {
int data[] = new int[3];
System.out.println("数组0:" + data[0]);
System.out.println("数组1:" + data[0]);
System.out.println("数组2:" + data[0]);
}
}
数组0:0
数组1:0
数组2:0
修改数组
public class Test {
public static void main(String[] args) {
int data[] = new int[3];
data[0] = 10;
data[1] = 20;
data[2] = 30;
System.out.println("数组0:" + data[0]);
System.out.println("数组1:" + data[1]);
System.out.println("数组2:" + data[2]);
}
}
数组0:10
数组1:20
数组2:30
数组静态初始化
数组采用了动态初始化之后其保存数据为对应数据类型默认值,而如果希望在数组定义时就可以明确的设置数组中的元素内容,则可以采用静态初始化语法,可以采用如下两类语法形式进行定义。
- 第一类:简化结构数组静态初始化定义格式
- 数据类型 [] 数组名称 ={数值,数值,… 数值};
- 数据类型 数组名称 [] ={数值,数值,…. 数值};
- 第二类:完整结构数组静态初始化定义格式
- 数据类型 [] 数组名称 = new 数据类型 []{数值, 数值,… 数值}
- 数据类型 数组名称 [] = new 数据类型 []{数值, 数值,… 数值}
范例
class sTest{
public static void main(String[] args) {
int data [] = new int[]{10,20,30};
System.out.println("数组0:" + data[0]);
System.out.println("数组1:" + data[1]);
System.out.println("数组2:" + data[2]);
}
}
数组0:10
数组1:20
数组2:30
class sTest {
public static void main(String[] args) {
int data[] = new int[]{10, 20, 30};
data[0] *= 2;
data[1] += 2;
data[2] = data[0] + data[1];
System.out.println("数组0:" + data[0]);
System.out.println("数组1:" + data[1]);
System.out.println("数组2:" + data[2]);
int data1[] = new int[]{1, 3, 3};
data1[2] *= data1[0] + data1[1];
System.out.println(data1[2]);
}
}
数组0:20
数组1:22
数组2:42
12
数组与 for 循环
范例
class forTest {
public static void main(String[] args) {
int data[] = new int[]{10, 20, 30};
//for循环输出数组
for (int i = 0; i < 3; i++) {
System.out.print(data[i] + "、");
}
System.out.println("数组长度:" + data.length);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "、");
}
}
}
10、20、30、数组长度:3
10、20、30、
foreach 输出
在传统编程中由于数组属于线性结构,所以只需要利用 for 循环实现下表索引的控制就可以方便的实现数组的输出,但是从 JDK-1.5 之后的版本中提供有一种更加方便的 foreach 结构,这种结构属于增强型 for 循环,利用这种结构可以帮助开发者回避数组的索引操作,该结构的语法如下所示
范例
class foreTest {
public static void main(String[] args) {
int data[] = new int[]{10, 20, 30};
for (int temp : data) {
System.out.print(temp + "、");
}
}
}
10、20、30、
数组引用分析
范例
class foreTest1 {
public static void main(String[] args) {
int data[] = new int[]{1, 3, 5};
int array[] = data;
array[1] = 90;
array[2] = array[0] + array[1];
for (int temp : data) {
System.out.print(temp + "、");
}
}
}
数组与方法
范例
/**
* 方法接收并引用
*/
class Test3 {
public static void main(String[] args) {
int data[] = new int[]{1, 3, 5};
printArray(data);
}
public static void printArray(int[] temps) {
for (int item : temps) {
System.out.println(item + "、");
}
}
}
1、3、5、
/**
* 通过类管理数组方法
*/
class ArrayUtil {
public static void change(int temps[]) {
//foreach无法修改变量值
// for (int temp : temps) {
// temp *= 2;
// }
for (int i = 0; i < temps.length; i++) {
temps[i] *= 2;
}
}
public static void printArray(int arrs[]) {
for (int i = 0; i < arrs.length; i++) {
System.out.print(arrs[i] + "、");
}
}
public static int[] init() {
return new int[]{1, 3, 5};
}
}
class UtilTest {
public static void main(String[] args) {
int data[] = ArrayUtil.init();
int a = 2;
a *= 2;
System.out.println(a);
ArrayUtil.change(data);
ArrayUtil.printArray(data);
}
}
4
2、6、10、
数组信息统计案例
数组信息统计案例
class ArraysSumUtils {
private int[] array;
private int max;
private int min;
private int avg;
private int sum;
public ArraysSumUtils(int[] array) {
this.array = array;
this.handle();
}
private void handle() {
this.max = this.array[0];
this.min = this.array[0];
for (int itm : this.array) {
if (this.max < itm) {
this.max = itm;
}
if (this.min > itm) {
this.min = itm;
}
this.sum += itm;
}
this.avg = this.sum / this.array.length;
}
public int getMax() {
return max;
}
public int getMin() {
return min;
}
public int getAvg() {
return avg;
}
public int getSum() {
return sum;
}
}
class SumTest {
public static void main(String[] args) {
int data[] = new int[]{5, 8, 4, 5, 1, 12, 5, 4, 5, 1};
ArraysSumUtils arraysSumUtils = new ArraysSumUtils(data);
System.out.println("最大值" + arraysSumUtils.getMax());
System.out.println("最小值" + arraysSumUtils.getMin());
System.out.println("平均值" + arraysSumUtils.getAvg());
System.out.println("求和值" + arraysSumUtils.getSum());
}
}
最大值12
最小值1
平均值5
求和值50
数组排序案例
- 数组是由一系列的数据所组成,在所有的组成数据之中由于用户设置的随意性,那么类组中所保存的内容有可能是无序的,但是无序的数据很难做出一些高效的数据处理,这样在实际的项目中就有了数组排序的需求,例如:现在假设有如下一个数组定义:。int data[]= new int []{3,1,5,2,8, 6,9, 0};
- 此时 data 数组中保存有 8 个数据内容,但是这些数据内容没有任何顺序,而要想进行有效的处理,则应该考虑按照数据的升序排列,即:“[0.1.2.3.5,6,8,9]”处理之后的 data 数组中的内容顺序,而这种排序操作就需要采用数组线性结构的特点来完成,利用索引的控制实现排序操作。
数组排序案例
//排序标记
private boolean isSort = false;
public void sort() {
if (!this.isSort) {
for (int i = 0; i < this.array.length; i++) {
for (int j = 0; j < this.array.length - 1; j++) {
if (this.array[j] > this.array[j + 1]) {
int temp = this.array[j];
this.array[j] = this.array[j + 1];
this.array[j + 1] = temp;
}
}
}
this.isSort = true;
}
}
public static void printArray(int[] datas) {
for (int data : datas) {
System.out.print(data + "、");
}
}
int data[] = new int[]{5, 8, 4, 5, 1, 12, 5, 4, 5, 1};
ArraysSumUtils arraysSumUtils = new ArraysSumUtils(data);
System.out.println("最大值" + arraysSumUtils.getMax());
System.out.println("最小值" + arraysSumUtils.getMin());
System.out.println("平均值" + arraysSumUtils.getAvg());
System.out.println("求和值" + arraysSumUtils.getSum());
arraysSumUtils.sort();
ArraysSumUtils.printArray(arraysSumUtils.getArray());
1、1、4、4、5、5、5、5、8、12、
数组转置案例
数组转置案例
//是否反转
private boolean isReverse = false;
public void reverse() {
if (!this.isReverse) {
int center = this.array.length / 2;
int head = 0;
int tail = this.array.length - 1;
for (int i = 0; i < center; i++) {
int temp = array[head];
array[head] = array[tail];
array[tail] = temp;
head++;
tail--;
}
this.isReverse = true;
}
}
class SumTest1 {
public static void main(String[] args) {
int data[] = new int[]{3, 1, 5, 8, 1, 12, 5, 4, 2, 1};
ArraysSumUtils arraysSumUtils = new ArraysSumUtils(data);
arraysSumUtils.reverse();
ArraysSumUtils.printArray(arraysSumUtils.getArray());
}
}
1、2、4、5、12、1、8、5、1、3、
二维数组
一维数组元素定位
数组变量与普通变量最大的区别在于数组定义时需要明确的使用“[]”进行标记,对于之前所讲解的所有数组可以发现只存在有一个“[]“,所以这样的数组可以称其为一维数组”,所有的一维数组只需要利用一个索引下标即可实现全部数组的操作控制
二维数组元素定位
如果说现在要想描述出多行多列的结构(表结构形式),那么就可以通过二维数组的形式进行定义,则在定义二维数组时就需要使用两个“[][]”声明,在二维数组中需要通过行下标与列下标共同才可以定位一个数据内容
二维数组初始化
如果要想在程序中进行二维数组的定义,那么可以采用动态初始化与静态初始化两种方式完成,具体定义语法如下:
- 动态初始化:
- 数据类型 数组名称 [][]=new 数据类型[行个数][列个数];
- 数据类型 [][] 数组名称 = new 数据类型[行个数][列个数];
- 静态初始化:
- 数据类型 数组名称 [][] ={{数据,数据,数据, ….},{数据, 数据,数据,...},….}
- 数据类型 数组名称 [][]= new 数据类型[][]{{数据, 数据,数据,..},{数据,数据,据,…},…}
详情
class ErTest {
public static void main(String[] args) {
int data[][] = new int[][]{{1, 3, 5}, {2, 4, 6, 8}, {9, 10}};
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
System.out.print(data[i][j] + "、");
}
System.out.println();
}
}
}
1、3、5、
2、4、6、8、
9、10、
JDK 内置数组操作方法
数组拷贝
从一个数组之中拷贝部分内容到另外一个数组之中,方法:System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝长度);
class SysTest {
public static void main(String[] args) {
int dataA[] = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
int dataB[] = new int[]{11, 22, 33, 44, 55, 66, 77, 88, 99};
System.arraycopy(dataA, 4, dataB, 2, 3);
for (int temp : dataB) {
System.out.print(temp + "、");
}
}
}
11、22、5、6、7、66、77、88、99
数组排序
可以按照由小到大的顺序对基本数据类型的数组(例如:int 数组、double 数组都为基本类型数组)进行排序,操作语法:java.util.Arrays.sort(数组名称)
class ArrTest {
public static void main(String[] args) {
int data[] = new int[]{8, 5, 6, 4, 2, 2, 5, 455, 57};
Arrays.sort(data);
for (int temp : data) {
System.out.print(temp + "、");
}
}
}
2、2、4、5、5、6、8、57、455
方法可变参数
可变参数
Java 为了方便开发者可以更加灵活的进行方法的定义,避免方法中参数的执行限制,所以提供有方法可变参数的支持,利用这一特点可以在方法调用时采用动态形式传递若干个参数数据,可变参数定义语法如下:
public [static] [final] 返回值类型 方法名称(参数类型 ...变量){
[return 返回值]
}
详情
class MathUtil {
public static int sum(int... args) {
int result = 0;
for (int x : args) {
result += x;
}
return result;
}
}
class MathTest {
public static void main(String[] args) {
System.out.println("两个参数" + MathUtil.sum(new int[]{8, 6, 58}));
System.out.println("两个参数" + MathUtil.sum(new int[]{8, 6}));
}
}
两个参数72
两个参数14
对象数组
对象数组
在 Java 中所有的数据类型均可以定义为数组,即:除了基本数据类型的数据定义为数组后,引用数据类型也可以定义数组,这样的数组就称为对象数组,对象数组的定义可以采用如下的形式完成:
- 对象数组动态初始化:
- 类名称 对象数组名称 []=new 类名称[长度]
- 类名称[] 对象数组名称 =new 类名称[长度];
- 对象数组静态初始化:
- 类名称 对象数组名称 []=new 类名称 []{对象实例,对象实例, 对象实例,….}
- 类名称[] 对象数组名称=new 类名称[]{对象实例,对象实例,对象实例,…};
详情
class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public String getInfo() {
return "名字叫" + name + "几岁:" + age;
}
}
class CatTest {
public static void main(String[] args) {
Cat[] cats = new Cat[3];
cats[0] = new Cat("lili", 2);
cats[1] = new Cat("week", 12);
cats[2] = new Cat("daku", 8);
for (Cat cat : cats) {
System.out.println(cat.getInfo());
}
}
}
名字叫lili几岁:2
名字叫week几岁:12
名字叫daku几岁:8
引用关联
在面向对象编程中,每一个类都可以明确的描述某一类实体特征,现在假设在生活中有这样一种场景:一个人有一辆汽车(或者没有汽车) 如果现在采用面向对象的设计方式那么一定要有两个类:描述人信息的类以及描述汽车信息的类,同时这两个类中彼此应该拥有各自类的引用属性以实现关联
自身关联
详情
合成设计模式
class 电脑{
private 显示器 对象数组[];
private 主机 对象;
}
class 显示器{}
class 主机{
private 主板 对象;
private 鼠标 对象;
private 键盘 对象;
}
class 主板{
private 内存 对象数组[];
private CPU 对象数组[];
private 显卡 对象;
private 硬盘 对象数组[];
}
class 键盘{}
class 鼠标{}
class 内存{}
class CPU{}
class CP显卡U{}
class 硬盘{}
数据表与类映射
部门表与简单 Java 类映射
程序类的定义形式实际上和这些实体表的差别并不大,所以在实际的项目开发之中数据表与简单 Java 类之间的基本映射关系如下:
- 简单 Java 类的类名称=数据表的表名称;
- 简单 Java 类中的属性名称及内容=数据表中数据列的名称及内容
- 简单 Java 类中的引用关联 =数据表中的外键或自身关联;
- 简单 Java 类的一个实例化对象=数据表中的一行数据信息:
- 简单 Java 类的多个实例化对象(对象数组)=数据表中的多行记录。
表关联关系
这个时候在表里面存在有如下的关联关系结构:
- 一个部门会保存有多个雇员的信息(多个雇员可以通过对象数组描述)- 一个雇员属于一个部门(每一个雇员一定要保存有部门的引用):
- 一个雇员存在有一位领导,领导一定也是一位雇员,所以应该使用一种自身关联的形式来进行处理。