7、数组概念
-
定义: 数组是相同类型数据的有序集合。
-
基本特点:
- 长度是确定的。
- 元素类型相同,不允许出现混合类型。
- 数组类型可以是任意数据类型,包括基本数据类型和引用数据类型。
-
数组声明
type[] arr_name;//(推荐使用)
type arr_name[];
注意事项:
- 声明的时候并没有实例化任何对象,只有在实例化数组时,JVM才分配空间,这时才与长度有关。
- 声明一个数组的时候并没有数组真正被创建。
- 构造一个数组必须指定长度。
- 基本数据类型数组内存分配图
public class Test {
public static void main(String args[]) {
int[] s = null; // 声明数组;
s = new int[10]; // 给数组分配空间;
for (int i = 0; i < 10; i++) {
s[i] = 2 * i + 1;//给数组元素赋值;
System.out.println(s[i]);
}
}
}
-
引用数据类型数组内存分配图
class Man{ private int age; private int id; public Man(int id,int age) { super(); this.age = age; this.id = id; } } public class AppMain { public static void main(String[] args) { Man[] mans; //声明引用类型数组; mans = new Man[10]; //给引用类型数组分配空间; Man m1 = new Man(1,11); Man m2 = new Man(2,22); mans[0]=m1;//给引用类型数组元素赋值; mans[1]=m2;//给引用类型数组元素赋值; } }
2、数组初始化
-
静态初始化
除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。
int[] a = { 1, 2, 3 };// 静态初始化基本类型数组; Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
-
动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行。
int[] a1 = new int[2];//动态初始化数组,先分配空间; a1[0]=1;//给数组元素赋值; a1[1]=2;//给数组元素赋值;
-
默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
int a2[] = new int[2]; // 默认值:0,0 boolean[] b = new boolean[2]; // 默认值:false,false String[] s = new String[2]; // 默认值:null, null
3、for-each循环
public class Test {
public static void main(String[] args) {
String[] ss = { "aa", "bbb", "ccc", "ddd" };
for (String temp : ss) {
System.out.println(temp);
}
}
}
注意事项
for-each增强for循环在遍历数组过程中不能修改数组中某元素的值。
for-each仅适用于遍历,不涉及有关索引(下标)的操作。
4、数组拷贝
System类里也包含了一个static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素赋给dest数组的元素。
public class Test {
public static void main(String args[]) {
String[] s = {"阿里","尚学堂","京东","搜狐","网易"};
String[] sBak = new String[6];
System.arraycopy(s,0,sBak,0,s.length);
for (int i = 0; i < sBak.length; i++) {
System.out.print(sBak[i]+ "\t");
}
}
}
5、java.util.Arrays类
JDK提供的java.util.Arrays类,包含了常用的数组操作,方便我们日常开发。Arrays类包含了:排序、查找、填充、打印内容等常见的操作。
//打印数组
import java.util.Arrays;
public class TestArrays{
public static void main(String[] args){
int[] a={1,2};
System.out.println(a);//打印数组引用的值
System.out.println(Arrays.toString(a));
}
}
6、多维数组
二维数组内存分配
7、冒泡排序算法
-
实现步骤
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
-
-
基础算法
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] values = { 3, 1, 6, 2, 9, 0, 7, 4, 5, 8 };
bubbleSort(values);
System.out.println(Arrays.toString(values));
}
public static void bubbleSort(int[] values) {
int temp;
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values.length - 1 - i; j++) {
if (values[j] > values[j + 1]) {
temp = values[j];
values[j] = values[j + 1];
values[j + 1] = temp;
}
}
}
}
}
-
优化算法
import java.util.Arrays; public class Test1 { public static void main(String[] args) { int[] values = { 3, 1, 6, 2, 9, 0, 7, 4, 5, 8 }; bubbleSort(values); System.out.println(Arrays.toString(values)); } public static void bubbleSort(int[] values) { int temp; int i; // 外层循环:n个元素排序,则至多需要n-1趟循环 for (i = 0; i < values.length - 1; i++) { // 定义一个布尔类型的变量,标记数组是否已达到有序状态 boolean flag = true; /*内层循环:每一趟循环都从数列的前两个元素开始进行比较,比较到无序数组的最后*/ for (int j = 0; j < values.length - 1 - i; j++) { // 如果前一个元素大于后一个元素,则交换两元素的值; if (values[j] > values[j + 1]) { temp = values[j]; values[j] = values[j + 1]; values[j + 1] = temp; //本趟发生了交换,表明该数组在本趟处于无序状态,需要继续比较; flag = false; } } //根据标记量的值判断数组是否有序,如果有序,则退出;无序,则继续循环。 if (flag) { break; } } } }
8、二分法查找
二分法检索(binary search)又称折半检索,二分法检索的基本思想是设数组中的元素从小到大有序地存放在数组(array)中,首先将给定值key与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功;
否则,若key小,则在数组前半部分中继续进行二分法检索;
若key大,则在数组后半部分中继续进行二分法检索。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = { 30,20,50,10,80,9,7,12,100,40,8};
int searchWord = 20; // 所要查找的数
Arrays.sort(arr); //二分法查找之前,一定要对数组元素排序
System.out.println(Arrays.toString(arr));
System.out.println(searchWord+"元素的索引:"+binarySearch(arr,searchWord));
}
public static int binarySearch(int[] array, int value){
int low = 0;
int high = array.length - 1;
while(low <= high){
int middle = (low + high) / 2;
if(value == array[middle]){
return middle; //返回查询到的索引位置
}
if(value > array[middle]){
low = middle + 1;
}
if(value < array[middle]){
high = middle - 1;
}
}
return -1; //上面循环完毕,说明未找到,返回-1
}
}
9、练习题
一、 选择题
1.在Java中,以下程序段能正确为数组赋值的是( ACD)。(选择二项)
A.
int a[]={1,2,3,4};
B.
int b[4]={1,2,3,4};
C.
int c[];
c=new int[] {1,2,3,4};
D.
int d[];d=new int[]{1,2,3,4};
2.已知表达式int [] m={0,1,2,3,4,5,6};下面(B )表达式的值与数组最大下标数相等。(选择一项)
A.
m.length()
B.
m.length-1
C.
m.length()+1
D.
m.length+1
3.在Java中,以下定义数组的语句正确的是(BC )。(选择二项)
A.
int t[10]=new int[ ];
B.
char [ ]a=new char[5];
char []a={‘a’,’b’};
C.
String [ ] s=new String [10];
D.
double[ ] d [ ]=new double [4][ ];
double[][] d;
double d[][];
4.分析下面的Java源程序,编译后的运行结果是( C )。(选择一项)
import java.util.*;
public class Test {
public static void main(String[ ] args) {
int [ ] numbers=new int[ ]{1,2,3};
//查找数组numbers中2的索引
System.out.println(Arrays.binarySearch(numbers, 2));
}
}
A.输出:0
B.输出:1
C.输出:2
D.输出:3
5.以下选项中能够正确创建一个数组的是( AD)。(选择二项)
A.
float []f[] = new float[6][6];
B.
float f[][] = new float[][];
C.
float [6][]f = new float[6][6];
D.
float [][]f = new float[6][];
二、 简答题
-
数组的特点。
- 其长度是确定
- 其元素是相同类型
- 可以存储基本数据类型和引用数据类型
- 数组变量属于引用数据类型
-
数组的优缺点
优点:高效率。
缺点:数组大小被固定。
-
冒泡排序的算法。
package com.zry.day06.lx; import java.util.Arrays; public class TestBubbleSort { public static void main(String[] args) { int[] arr= { 3, 1, 6, 2, 9, 0, 7, 4, 5, 8 }; bubbleSort(arr); System.out.println(Arrays.toString(arr)); } public static void bubbleSort(int[] arr) { int temp; int i; int j; boolean flag; for(i=0;i<arr.length;i++) { flag=true; for(j=0;j<arr.length-1-i;j++) { System.out.print(j); if(arr[j]>arr[j+1]) { temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; flag=false; } } if(flag) { break; } } } }
时间复杂度:O(n)
空间复杂度:O(n^2)
-
数组的三种初始化方式是什么?
静态初始化、动态初始化、默认初始化。
三、 编码题
-
数组查找操作:定义一个长度为10 的一维字符串数组,在每一个元素存放一个单词;然后运行时从命令行输入一个单词,程序判断数组是否包含有这个单词,包含这个单词就打印出“Yes”,不包含就打印出“No”。
package com.zry.day06.lx; import java.util.Scanner; public class SelectArrays { public static void main(String[] args) { String[] str=new String[10]; str=new String[] {"yes","no","hello","hi","word","teacher","student","how","are","you"}; Scanner sc=new Scanner(System.in); System.out.print("请输入一个单词:"); String word=sc.next(); System.out.print("数组里是否包含单词"+word+"?:"); if(exist(str,word)) { System.out.println("Yes"); }else { System.out.println("No"); } } static boolean exist(String[] str,String word) { for(String s:str) { if(s.equals(word)) { return true; } } return false; } }
-
获取数组最大值和最小值操作:利用Java的Math类的random()方法,编写函数得到0到n之间的随机数,n是参数。并找出产生50个这样的随机数中最大的、最小的数,并统计其中>=60的有多少个。
提示:使用 int num=(int)(n*Math.random());获取随机数。
package com.zry.day06.lx; import java.util.Arrays; public class RandomStatistics { public static void main(String[] args) { int[] arr=new int[50]; int n=100; arr=random(arr, n); System.out.println(Arrays.toString(arr)); numMax(arr); numMin(arr); count(arr); } public static int[] random(int[] arr,int n) { for(int i=0;i<arr.length;i++) { arr[i]=(int)(n*Math.random()); } return arr; } public static void numMax(int[] arr) { int max=arr[0]; for(int i:arr) { if(i>max) { max=i; } } System.out.println("最大值为:"+max); } public static void numMin(int[] arr) { int min=arr[0]; for(int i:arr) { if(i<min) { min=i; } } System.out.println("最小值为:"+min); } public static void count(int[] arr) { int count=0; System.out.print(">=60的数有"); for(int i:arr) { if(i>=60) { count++; System.out.print(i+" "); } } System.out.println("\n>=60的数一共有"+count+"个"); } }
-
数组逆序操作:定义长度为10的数组,将数组元素对调,并输出对调前后的结果。
思路:把0索引和arr.length-1的元素交换,把1索引和arr.length-2的元素交换……
只要交换到arr.length/2的时候即可。
package com.zry.day06.lx;
import java.util.Arrays;
public class ArrayOrder {
public static void main(String[] args) {
int arr[]= {0,1,2,3,4,5,6,7,8,9};
System.out.println("原数组:"+Arrays.toString(arr));
for(int i=0;i<arr.length/2;i++) {
int temp=arr[i];
arr[i]=arr[arr.length-i-1];
arr[arr.length-i-1]=temp;
}
System.out.println("目标数组:"+Arrays.toString(arr));
}
}
- 数组逆序操作:定义长度为10的数组,将数组元素对调,并输出对调前后的结果。
思路:把0索引和arr.length-1的元素交换,把1索引和arr.length-2的元素交换……
只要交换到arr.length/2的时候即可。
package com.zry.day06.lx;
import java.util.Arrays;
public class ArrayOrder {
public static void main(String[] args) {
int arr[]= {0,1,2,3,4,5,6,7,8,9};
System.out.println("原数组:"+Arrays.toString(arr));
for(int i=0;i<arr.length/2;i++) {
int temp=arr[i];
arr[i]=arr[arr.length-i-1];
arr[arr.length-i-1]=temp;
}
System.out.println("目标数组:"+Arrays.toString(arr));
}
}