一维数组 ◼ 一维数组的定义
1 2 3 4 5 6 7 int a[5]; × // Java数组定义时一定不要指定长度 int a[ ]; √ // 过时写法 (中括号放在数组名后面) int[ ] a; √ // 推荐形式 (中括号放在类型后面) int[ ] s1, s2; // s1,s2都是整型数组 int s1[ ], s2; // s1是整型数组,s2是整型变量 String[ ] names; // 字符串数组 Point[ ] p; // 对象数组
◼ Java数组要求所有的元素具有相同的数据类型
◼ Java数组是引用类型,例如:int 是一个基本类型,但 int[] 是一种引用类型
◼ Java数组既可以存储基本类型的数据,也可以存储引用类型的数据,只要所有的数组元素具有相同的类型即可
一维数组的初始化
◼ 用new语句来初始化数组:
1 2 int [ ] a = new int [5 ]; a[0 ] = 1 ; a[1 ] = 2 ; … a[4 ] = 5 ;
1 2 3 4 5 6 7 int [] b; b = new int [5 ]; int n = 5 ; int [] c = new int [n] ; c = new int [10 ];
快速初始化数组
1 2 int [] a = { 1 , 2 , 3 , 4 , 5 }; int [] a = new int [ ] { 1 ,2 ,3 ,4 ,5 };
注意:int[ ] a=new int[5]{ 1,2,3,4,5 }; 指定长度 ×
1 2 String[ ] names = { "Tom" , "Jerry" , "Simon" } ; Point[ ] p = { new Point (0 ,1 ), new Point (1 ,2 ) };
一维数组遍历:使用 length 属性
1 2 3 4 5 6 7 8 9 int [ ] arr = { 1 , 2 , 3 , 4 , 5 };for ( int i = 0 ; i < arr.length; i++) { arr[i] += 100 ; } for ( int i = arr.length-1 ; i >= 0 ; i--) { System.out.println( "arr[" + i + "]=" + arr[i] ); } System.out.println( arr ); System.out.println( Arrays.toString(arr) );
Arrays.toString(数组):将数组转化为字符串
一维数组遍历的新方法 ★
◼ for-each循环基本结构
1 2 3 4 5 for ( 类型 变量 : 数组 ) { }
示例:for-each循环遍历数组
1 2 3 4 int [ ] arr = { 1 , 2 , 3 , 4 , 5 };for ( int a : arr ) { System.out.println(a); }
程序阅读
Main.java
1 2 3 4 5 6 7 8 9 public class Main { public static void main (String[] args) { int [ ] arr = { 1 , 2 , 3 , 4 , 5 }; for ( int a : arr ) { a += 100 ; } System.out.println( Arrays.toString(arr) ); } }
关于数组传参问题
◼ 在Java中,基本类型总是按值传递
◼ 对象类型为 传引用 (如数组,包装类,集合类等)
注意: 传引用仍然视为值传递!!! 对于对象来说,是将对象的引用也就是 副本 传递给了方法参数,在方法中 只有对对象进行修改才能影响该对象的值 , 操作对象的引用是无法影响对象的 。
Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Main { public static void swap1 (int a, int b) { int c=a; a=b; b=c; } public static void swap2 ( int [ ] a ) { a = new int [] { 99 , 10 }; } public static void swap3 ( int [ ] a ) { int c = a[0 ]; a[0 ] = a[1 ]; a[1 ] = c; } public static void main (String[] args) { int a=2 , b=3 ; System.out.println("a=" +a+",b=" +b); swap1(a,b); System.out.println("a=" +a+",b=" +b); int [] arr = { 10 ,99 }; System.out.println(Arrays.toString(arr)); swap2(arr); System.out.println(Arrays.toString(arr)); swap3(arr); System.out.println(Arrays.toString(arr)); } }
程序阅读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Main { public static void foo1 ( int [ ] a ) { a = new int [ ] {1 , 2 , 3 }; } public static void foo2 ( int [ ] a ) { if ( a != null && a.length > 0 ) a[0 ]++; } public static void main (String[] args) { int [ ] aa = { 3 , 2 , 1 }; System.out.println( Arrays.toString(aa) ); foo1(aa); System.out.println( Arrays.toString(aa) ); foo2(aa); System.out.println( Arrays.toString(aa) ); } }
可变参数
◼ 可变参数用 … 定义,例如:int ...x;
◼ 适用于参数个数不确定,类型确定的情况
◼ 可变参数当做数组来处理
可变参数示例
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Main { public static void main (String[] args) { System.out.println( add(2 , 3 ) ); System.out.println( add(2 , 3 , 5 ) ); } public static int add ( int x, int ... args ) { int sum = x; for ( int i = 0 ; i < args.length; i++ ) { sum += args[i] ; } return sum; } }
二维数组 ◼ 二维数组创建:
1 2 3 4 5 6 int [ ][ ] a = new int [3 ][3 ]; 或者: int [ ][ ] a = new int [3 ][ ]; a[0 ] = new int [3 ]; a[1 ] = new int [3 ]; a[2 ] = new int [3 ];
注意:二维数组的第二维大小可不相等
1 2 3 4 int [ ][ ] a = new int [3 ][ ]; a[0 ] = new int [1 ]; a[1 ] = new int [2 ]; a[2 ] = new int [3 ];
二维数组初始化
◼ 方式1:普通赋值
1 2 int [ ][ ] a = new int [3 ][3 ]; a[0 ][0 ] = 1 ; a[0 ][1 ] = 2 ; … a[2 ][2 ] = 9 ;
◼ 方式2:一行行赋值(每行视为一维数组)
1 2 int [ ][ ] a= new int [3 ][ ];a[0 ] = new int [ ] {1 }; a[1 ] = new int [ ] {4 ,5 }; a[2 ] = new int [ ] {7 ,8 ,9 };
◼ 方式3:简单用法
1 2 int [ ][ ] a= { {1 ,2 ,3 }, {4 ,5 ,6 } , {7 ,8 ,9 } }; int [ ][ ] b= { {1 }, {4 ,5 } , {7 ,8 ,9 } };
二维数组遍历:使用length属性
1 2 3 4 5 6 int [ ][ ] a = { {1 }, {4 ,5 } , {7 ,8 ,9 } }; for ( int i=0 ; i < a.length ; i++) { for (int j=0 ; j < a[i].length ; j++) System.out.print(String.format("%3d" , a[i][j] ) ); System.out.println(); }
二维数组遍历:使用for-each循环
1 2 3 4 5 6 7 int [][] a= { {1 }, {4 ,5 } , {7 ,8 ,9 } }; for ( int [] x : a ) { for ( int e : x ) { System.out.print(String.format("%3d" , e)); } System.out.println(); }
思考:如何按列输出不规则二维数组?即上例输出为:1 4 7 5 8 9
数组编程 数组最大/小值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Ex_1 { private static int max,min; public static void maxmin ( int [ ] q ) { max = min = q[0 ]; for (int i=1 ;i<q.length;i++) { if ( max<q[i] ) max=q[i]; if ( min>q[i] ) min=q[i]; } } public static void main (String[] args) { int [ ] arr = { 9 ,3 ,18 ,5 ,6 ,1 ,10 ,15 }; System.out.println(Arrays.toString(arr)); maxmin( arr ); System.out.println("最大值:" +max+ "\n最小值:" +min); } }
数组排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Ex_2 { public static void bubble_sort ( int [ ] a ) { for (int i = 0 ; i < a.length - 1 ; i++) { for (int j = 0 ; j < a.length - i - 1 ; j++) { if (a[j] > a[j+1 ]) { int tmp = a[j]; a[j] = a[j+1 ]; a[j+1 ] = tmp; } } } } public static void main (String[] args) { int [ ] arr = { 28 , 12 , 89 , 73 , 65 , 18 , 96 , 50 , 8 , 36 }; System.out.println( Arrays.toString(arr) ); bubble_sort ( arr ); System.out.println( Arrays.toString(arr) ); } }
获取命令行参数
◼ 命令行参数:在运行Java程序时,可以通过命令行参数传值给main函数
示例:对命令行输入的多个整数求和
1 2 3 4 5 6 7 8 9 10 public class Ex_3 { public static void main (String[] args) { int sum=0 ; for ( int i=0 ; i < args.length; i++ ) { sum += Integer.parseInt( args[i] ); } System.out.println( Arrays.toString(args) ); System.out.println("和=" +sum); } }
补充:main参数也可写成可变参数: public static void main(String… args)
如何输入(配置)命令行参数
for-each循环
修改2.6章节例1
原例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void count (String s) { for ( int i = 0 ; i < s.length(); i++ ) { char ch = s.charAt(i); if ( Character.isLowerCase(ch) ) lower++; else if ( Character.isUpperCase(ch) ) upper++; else if ( Character.isDigit(ch) ) number++; else if ( Character.isWhitespace(ch) ) space++; else other++; } }
修改如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void count (String s) { char [ ] chArr = s.toCharArray(); for ( char ch : chArr ) { if ( Character.isLowerCase(ch) ) lower++; else if ( Character.isUpperCase(ch) ) upper++; else if ( Character.isDigit(ch) ) number++; else if ( Character.isWhitespace(ch) ) space++; else other++; } }
Fibonacci数列
非递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Ex_5 { public static void main (String[] args) { int n = 20 ; int arr[ ] = new int [n]; fib(arr); for ( int x:arr ) { System.out.print(String.format("%d " , x)); } } public static void fib (int [] a) { a[0 ] = a[1 ] = 1 ; for ( int i = 2 ; i < a.length; i++ ) a[i] = a[i - 1 ] + a[i - 2 ]; } }
递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Ex_5 { public static void main (String[] args) { int n = 20 ; int arr[] = new int [n]; for (int i = 0 ; i < n; i++) { arr[i] = fab( i ); } for ( int x:arr ) { System.out.print(String.format("%d " , x)); } } public static int fab (int n) { if (n == 0 || n == 1 ) return 1 ; else return fab(n - 1 ) + fab(n - 2 ); } }
杨辉三角型
输出10行
非递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Ex_6 { public static void yang (int [][] a) { for (int i = 0 ; i < a.length; i++) { a[i] = new int [i + 1 ]; a[i][0 ] = 1 ; a[i][i] = 1 ; } for (int i = 2 ; i < a.length; i++) for (int j = 1 ; j < a[i].length-1 ; j++) a[i][j] = a[i - 1 ][j - 1 ] + a[i - 1 ][j]; } public static void main (String[] args) { int n = 10 ; int a[][] = new int [n][]; yang(a); for (int i = 0 ; i < a.length; i++) { for (int j = 0 ; j < a[i].length; j++) System.out.print(String.format("%-4d" , a[i][j])); System.out.println(); } } }
递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Ex_6 { public static int yang (int i, int j) { if (j == 0 || i == j) return 1 ; return yang(i - 1 , j - 1 ) + yang(i - 1 , j); } public static void main (String[] args) { int n = 10 ; int a[][] = new int [n][]; for (int i = 0 ; i < n; i++) a[i] = new int [i + 1 ]; for (int i = 0 ; i < a.length; i++) for (int j = 0 ; j < a[i].length; j++) a[i][j] = yang( i, j ); for (int i = 0 ; i < a.length; i++) { for (int j = 0 ; j < a[i].length; j++) System.out.print(String.format("%-4d" , a[i][j])); System.out.println(); } } }
附录 【附录1】几种排序方法
选择排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static void select_sort (int [] arr) { for (int i = 0 ; i < arr.length - 1 ; i++) { int minIndex = i; for (int j = i + 1 ; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (i != minIndex) { int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } }
选择排序算法思想:遍历元素找到一个最小(或最大)的元素,把 它放在第一个位置,然后再在剩余元素中找到最小(或最大)的元 素,把它放在第二个位置,依次下去,完成排序。
插入排序
1 2 3 4 5 6 7 8 9 10 11 12 13 public static void insert_sort (int [] arr) { int j; int t; for (int i = 1 ; i < arr.length; i++) { if (arr[i] < arr[i - 1 ]) { t = arr[i]; for (j = i - 1 ; j >= 0 && arr[j] > t; j--) { arr[j + 1 ] = arr[j]; } arr[j + 1 ] = t; } } }
插入排序算法思想:
① 从第一个元素开始,该元素可以认为已经排好序。
② 取出下一个新元素,然后把这个新元素在已经排好序的元素序列中从后往前扫描进行比较。
③ 如果该元素(已排序)大于新元素,则将这个已排序的元素移到下一个索引位置。
④ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置。
⑤ 将新元素插入到该已排序的元素的索引位置后面。
⑥ 重复步骤②-⑤
快速排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public static int [] quick_sort(int [] arr, int left, int right) { if (left < right) { int partitionIndex = partition(arr, left, right); quick_sort(arr, left, partitionIndex - 1 ); quick_sort(arr, partitionIndex + 1 , right); } return arr; } public static int partition (int [] arr, int left, int right) { int pivot = left; int index = pivot + 1 ; for (int i = index; i <= right; i++) { if (arr[i] < arr[pivot]) { swap(arr, i, index); index++; } } swap(arr, pivot, index - 1 ); return index - 1 ; } public static void swap (int [] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
快速排序算法思想:
① 从数列中挑出一个元素,称为 “基准”(pivot)
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在 基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的 中间位置。这个称为分区(partition)操作;
③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序.
【附录2】Arrays类用法
import java.util.Arrays;
◼ Arrays是针对数组的工具类,提供了排序,查找,复制填充,二分查找等功能, 大大提高了开发效率
Arrays常用方法
说明
sort(array)
对指定的基本数据类型数组array按升序排列
binarySearch(array,val)
对基本数据类型数组array进行二分查找val
equals(array1,array2)
如果两个指定的基本数据类型数组长度和内容都相等返回true
fill(array,val)
将指定的基本数据类型值数组array的所有元素都赋值为val (填充)
copyof(array,length)
把基本数据类型数组array复制成一个长度为length的新数组
toString(array)
把基本数据类型数组array内容转换为字符串
asList(T… a)
把数组a转换成List集合(注:不可以使用集合的增删方法)
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int [] a = new int [] { 3 , 4 , 5 , 6 };int [] a2 = new int [] { 3 , 4 , 5 , 6 };System.out.println("a数组和a2数组是否相等:" + Arrays.equals(a, a2)); int [] b = Arrays.copyOf(a, 6 );System.out.println("a数组和b数组是否相等:" + Arrays.equals(a, b)); System.out.println("b数组的元素为:" + Arrays.toString(b)); Arrays.fill(b, 2 , 4 , 1 ); System.out.println("b数组的元素为:" + Arrays.toString(b)); Arrays.sort(b); System.out.println("b数组的元素为:" + Arrays.toString(b)); System.out.println("查找1位置为:" + Arrays.binarySearch(b,1 )); System.out.println("查找2位置为:" + Arrays.binarySearch(b,2 ))