说到数组,我们不得不说它的实用之处,数组的运用很广泛,那么它对应的操作也就相当普遍了,这节我们就学习一些由数组引发的常见操作,对我们以后的帮助是很大的。
数组作为一个容器,存储了我们要访问和操作的各种数据,那么我们要访问和操作数据,也就是我们首先要访问和操作的就是容器,也就是我们现在说的数组。
对于数据,我们大多操作就是读和写,那么对于数组,我们对应的就是取和存。
**数组的遍历**
当然,我们要操作数组中的数据,我们首先要做的第一个动作就是找数据,也就是遍历,这是数组操作中最常见的操作之一。下面我们看一个遍历的小例子:
~~~
class ArrayDemo3 //数组的遍历
{
public static void main(String[] args)
{
int[] arr = {89,34,54,78};//静态初始化方式
System.out.println(arr[2]);
for(int i=0;i<arr.length;i++)//length是数组的一个属性,长度
{
System.out.print("arr["+i+"]="+arr[i]+"\t");
}
}
}
~~~
结果:
![](https://box.kancloud.cn/2016-05-18_573c4171cf25c.jpg)
我们可以看到数组的遍历操作的核心思想就是对数组索引的操作,通过索引访问数组中的每一个元素。
**数组的最值**
说到数组,我们知道它里面存储了相当类型的多个数据,那么我们会经常用到找出该数组中的最值的问题,下面我们看一下数组最值的问题:
我们这里以获取最大值为例子:
~~~
class ArrayDemo4 //数组的最值
{
public static void main(String[] args)
{
int[] arr = new int[]{32,54,65,78,93};
System.out.println("第"+(getMaxIndex(arr)+1)+"个元素"+getMaxElement(arr)+"是最大元素");
}
/*
思路:
1.需要进行比较,并定义变量记录每次比较后较大的值
2.对数组中的元素进行遍历,和变量中记录的元素进行比较
如果遍历到的元素大于变量的值,就把该元素的值符给变量
3.遍历结束,变量记录的就是最大值
*/
//这个方法用来获取一个数组元素中的最大值
public static int getMaxElement(int[] arr)
{
int maxElement = arr[0];//用来记录遍历过的元素中的最大数
for(int i=1;i<arr.length;i++)
{
if(arr[i] > maxElement)
{
maxElement = arr[i];
}
}
return maxElement;
}
//这个方法获取一个数组元素中的最大元素的角标
public static int getMaxIndex(int[] arr)
{
int maxIndex = 0;//用来记录遍历过的元素中的最大数的角标
for(int i=1;i<arr.length;i++)
{
if(arr[i] > arr[maxIndex])
{
maxIndex = i;
}
}
return maxIndex;
}
}
~~~
结果:
![](https://box.kancloud.cn/2016-05-18_573c4171e5356.jpg)
从上面的代码我们可以看出我在获取一数组的最大值时采用了两个不同的方法,一种直接获取数组元素中的最大值,一个方法获取了数组元素中最大元素的索引,这两个方法最终的目标都是获取了数组中的最大元素。
**数组的排序**
说到数组,我们又不得不说是就是排序,这个是我们以后实践中最容易用到的。
说到排序,我们知道排序的算法有很多,这里我们只看选择排序和冒泡排序两种排序方法:
1.选择排序:就是我们先选择一个索引为i的位置,用来存放索引为i~最后一个元素之间的最小元素
~~~
public static void selectSort(int[] arr)
{
for(int i=0;i<arr.length-1;i++)//先选择一个位置,进行遍历的次数,对于最后一个元素,不需要再遍历,所以i<arr.length-1
{
for(int j=i+1;j<arr.length;j++)//第i轮遍历的元素个数,把最小的元素放到arr[i]中
{
if(arr[j]<arr[i])//当后面的元素小于前面的元素,两个元素交换
{
//int temp = arr[i];
//arr[i] = arr[j];
//arr[j] = temp;
swap(arr,i,j);
}
}
}
}
~~~
这就是一个选择排序的算法,通过对上面方法的分析可以看出,每一次内循环比较满足条件时都会对元素进行一次转换,这样转换次数非常频繁。我们可以对上面的方法进行优化,通过减少元素的转换次数这个途径。
优化后的代码:
~~~
public static void selectSort_2(int[] arr)
{
for(int i=0;i<arr.length-1;i++)//先选择一个位置,进行遍历的次数,对于最后一个元素,不需要再遍历,所以i<arr.length-1
{
int num = arr[i];//存放对应轮数的最小值
int index = i;//记录这个最小值的索引
for(int j=i+1;j<arr.length;j++)//第i轮遍历的元素个数,把最小的元素放到arr[i]中
{
if(arr[j]<num)//当后面的元素小于前面的元素,则用num记录较小的内容,用index记录较小元素的索引
{
num = arr[j];
index = j;
}
}
if(index != i)//如果index的值不是i,就把这两个位置的元素进行置换,如果相等,就说明i对应的元素就是该轮的最小元素
{
swap(arr,i,index);
}
}
}
~~~
在上面的代码中我们通过定义两个变量,一个用来存放最小元素,一个用来存放最小元素对应的索引,这样我们可以通过记录最小元素索引的方式,记住最小元素,然后当每一轮结束之后把最小的元素放到对应的数组位置中(位置置换),这样就每一轮我们最多就只进行一次位置的置换。
2.冒泡排序:通俗的说冒泡排序就是像气泡一样把最大的元素移动到相应的位置。实际算法对于的第i轮,把0~i之间的元素通过相邻元素依次比较,把最大的元素移动到索引为i的位置。
~~~
//冒泡排序
public static void bubbleSort(int[] arr)
{
for(int i=0;i<arr.length-1;i++)//遍历的次数
{
for (int j=0; j<arr.length-i-1; j++)//-x:为了让外循环增加一次,内循环参数与比较的元素个数递减;-1是为了避免角标越界.
{
if(arr[j]>arr[j+1])//相邻元素进行比较,把较大的元素向上移动
{
//int temp = arr[j];
//arr[j] = arr[j+1];
//arr[j+1] = temp;
swap(arr,j,j+1);
}
}
}
}
~~~
下面我们对上面的两种排序方法进行一下测试,测试之前我们为了提高代码复用性,对元素位置置换和数组打印两个功能进行了独立封装。
~~~
//位置置换
public static void swap(int[] arr,int a,int b)//这个要注意参数的确定,这里是数组的两个元素在置换
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
~~~
~~~
//数组的打印,我们专门把数组的打印独立封闭起来
public static void printArray(int[] arr)
{
System.out.print("[");
for(int i=0;i<arr.length;i++)
{
if(i!=arr.length-1)//判断取掉最后一个','号
System.out.print(arr[i]+",");
else
System.out.println(arr[i]+"]");
}
}
~~~
下面看测试代码和结果
~~~
class ArrayDemo5
{
public static void main(String[] args)
{
int[] arr = new int[]{23,9,54,41,64,35,7,22};
int[] arr2 = new int[]{43,63,12,41,136,8,55,108};
printArray(arr);
//selectSort(arr);
selectSort_2(arr);
printArray(arr);
printArray(arr2);
bubbleSort(arr2);
printArray(arr2);
}
}
~~~
结果:
![](https://box.kancloud.cn/2016-05-18_573c4172050df.jpg)
- 前言
- 1.1 基本常识
- 1.2 Java语言概述
- 1.3 Java语言的环境搭建
- 1.4 Java程序开发之初体验--Hello World
- 2.1 关键字
- 2.2 标识符
- 2.3 注释
- 2.4 常量
- 2.5 进制扫盲
- 2.6 变量和数据类型(1)
- 2.7 变量和数据类型(2)
- 2.8 运算符
- 3.1 if语句
- 3.2 switch语句
- 3.3 while和do-while语句
- 3.4 for语句
- 3.5 for循环的嵌套
- 3.6 break语句与continue语句
- 4.1 函数的定义
- 4.2 定义函数的两个明确
- 4.3 函数的内存加载过程
- 4.4 函数的重载
- 5.1 数组的定义
- 5.2 数组的内存分配及特点
- 5.3 数组操作中常见问题
- 5.4 数组常用操作(1)
- 5.5 数组常用操作(2)
- 5.6 二维数组
- 6.1 面向对象的概述
- 6.2 类与对象的关系
- 6.3 对象的内存体现
- 6.4 成员变量与局部变量
- 6.5 类类型参数与匿名对象
- 6.6 基本数据类型参数与引用数据类型参数的传递过程
- 6.7 封装
- 7.1 构造函数概述与默认构造函数
- 7.2 构造函数与一般函数的区别
- 7.3 构造函数的重载
- 7.4 构造函数的内存加载
- 7.5 构造函数需要注意的几个细节
- 7.6 this关键字的原理
- 7.7 this关键字的细节与应用
- 8.1 static关键字之特点
- 8.2 成员变量与静态变量的区别
- 8.3 static关键字使用的注意细节
- 8.4 main函数的解析与细节
- 8.5 static关键字的使用场景
- 8.6 静态的内存加载
- 8.7 静态代码块
- 8.8 构造代码块
- 9.1 继承
- 9.2 单继承与多重继承
- 9.3 子父类中成员变量特征体现