Java语言基础9--引用数据类型之数组
什么是数组
数组是一种数据结构,用来存储同一类型的集合.
数组中的每一个数据称之为数组元素,数组中的元素以索引来表示其存放的位置,索引从0开始.
数组的定义
第一种方式:类型[] 数组名; 如 int[] nums; **
第二种方式:类型 数组名[]; 如 int nums[];**
大多数Java程序员喜欢使用第一种风格,因为它把数据类型int[],和变量名num分开了.
数组的初始化
Java中数组必先初始化后才能使用.
初始化就是给数组元素分配内存,并为每个元素赋初始值。
初始化数组的两种方式:
- 静态初始化:
语法格式:类型[] 数组名 = new 数组类型[]{元素1,元素2,元素3,...元素n};
简化语法:类型[] 数组名 = {元素1,元素2,元素3...元素n};
- 动态初始化:
如果我们事先不知道数组里存储哪些数据,只知道需要存储数据的个数,此时可以使用动态初始化方式。
动态初始化:初始化时由我们指定数组的长度,系统自动为数组元素分配初始值。
格式:类型[] 数组名 = new 数组类型[数组长度];
//数组初始化
public class InitDemo {
public static void main(String[] args) {
//静态初始化
int[] num = new int[] { 1, 2, 3, 4, 5 };
int[] num1 = { 1, 2, 3, 4, 5 };//简单写法
//只知道要存放数据的个数,不知道具体内容--动态初始化
int[] num2 = new int[5];//不同数据的动态初始化会有不同的初始值
}
}
注意:无论,以哪种方式初始化数组,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化。也就是说数组是定长的。如果需要经常扩展数组的大小,应该使用另一种数据结构--数组列表(ArrayList).
数组初始化内存分析
数组初始化内存分析.png 一维数组内存分析简单数组排序算法
- 冒泡排序(Bubble Sort):
思路:对未排序的各元素从头到尾依次比较相邻的两个元素大小关系,若大于则交换位置,经过第一轮比较排序后可得出最大值,然后使用同样的方法把剩下的元素逐个比较即可。
如果一共有N个元素,那么一共要进行N-1轮比较,第M轮要进行N-M次比较。
import java.util.Arrays;
//冒泡排序 -- 升序为例
public class BubbleSortDemo {
public static void main(String[] args) {
int[] num = { 13, 6, 2, 1, 4, 7, 8, 9 };
bubbleSort(num);
System.out.println(Arrays.toString(num));
Arrays.binarySearch(num, 5);
}
private static void bubbleSort(int[] a) {
//1.确定比较次数,N个元素,就要比较N - 1次
for (int time = 1; time <= a.length - 1; time++) {
//2.每次都是从最低位(索引为0处)开始,进行相邻的数值比较,第一轮出最大值
//类似于水里冒泡泡,每次都是水底开始,大的气泡先浮上来
for (int index = 0; index < a.length - time; index++) {
if (a[index] > a[index + 1]) {
int temp = a[index];
a[index] = a[index + 1];
a[index + 1] = temp;
}
}
}
}
}
- 选择排序(Selection Sort):
基本思路:选择某个索引位置的元素,然后和后面元素依次比较,若大于则交换位置,经过第一轮比较排序后可得出最小值,然后使用同样的方法把剩下的元素逐个比较即可。
第一轮会选出最小值,第二轮会选出第二小的值,直到最后。
选择排序每一轮只进行一次交换,相对于冒泡排序效率高一些。
import java.util.Arrays;
//选择排序--以升序为例
public class SelectionSortDemo {
public static void main(String[] args) {
int[] num = { 12, 13, 2, 1, 4, 7, 8, 9 };
selectionSort(num);
System.out.println(Arrays.toString(num));
}
public static void selectionSort(int[] num) {
//1.N个数要进行N-1轮
for (int time = 1; time < num.length; time++) {
//选择排序,类似于排队,找出最矮的,放在第一位,第二矮的放在第二位....
for (int index = time; index < num.length; index++) {
if (num[time - 1] > num[index]) {
int temp = num[index];
num[index] = num[time - 1];
num[time - 1] = temp;
}
}
}
}
}
-二分查找(折半查找)
采用二分法查找时,数据需是排好序的
二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.
当数据量很大适宜采用该方法。
例如:猜数游戏:
猜一个从1到100之间的数,为了能用最少的次数猜中,必须从50开始猜。如果你猜的偏小了,那么就能推出那个数在50到100之间,所以马上猜75。但如果你猜偏大了,你也能明白哪个说在1到50之间,所以马上猜25。如此重复,范围越来越小,直到猜到为止。
//二分法查找--前提:数组是有序的,一般都是升序
public class BinarySearchDemo {
public static void main(String[] args) {
int[] num = { 1, 3, 5, 7, 9 };
int ret = binarySearch(num, 5);
System.out.println(ret);
}
private static int binarySearch(int[] num, int key) {
int low = 0;
int high = num.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;//右移1位,就是除以2,但是效率更高
int midVal = num[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid;
}
return -1;
}
}
多维数组
如果每个变量都是一维数组,那这个装多个一维数组的数组是什么呢?也就是说现在数组里还有数组,此时我们习惯称为二维数组,同理什么是三维数组呢?
一维数组:数组中的每一个元素都是一个值.
二维数组:数组在的每一个元素都是一维数组.
三维数组:数组中的每一个元素都是二维数组.
注意:在Java中没有真正的多维数组的概念,我们习惯称之为数组中的数组.
注意区分和C/C++中的多维数组
详细可以看这篇文章:http://blog.csdn.net/u012110719/article/details/46288893
二维数组内存分析
二维数组内存分析.png方法的可变参数
遇到什么问题
求两个数之和,需要一个方法,该方法有两个参数,求5个数之和,需要重载一个方法,该方法有5个参数,求100个数之和、1000个数之和、10000个数之和,方法的参数列表会很长很长
我们使用数组解决了同类型的多参数问题.但是,调用者需要先把数据封装到一个数组中,再传递给求和方法.,很不爽!
怎么解决
解决方案:使用方法的可变参数机制.
方法的可变参数其实底层就是数组.
** 注意:**
1:可变参数只能运用于方法的参数中.
2:其本质就是数组,是Java5的一个语法糖.
3:可变参数必须作为方法的最后一个参数.
//方法的可变参数
public class AlterArgsDemo {
public static void main(String[] args) {
int ret = getSum(1, 2, 3);
System.out.println(ret);//6
ret = getSum(1, 2);
System.out.println(ret);//3
ret = getSum(1, 2, 3, 4, 5);
System.out.println(ret);//15
}
public static int getSum(int... arr) {
int sum = 0;
for (int i : arr) {
sum += i;
}
return sum;
}
}