6.1 一维数组的定义
- 数组的定义:
数组元素类型[] 数组名=new 数组元素类型[数组元素的个数]; - 数组内存分析:
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr=new int[5];
change(arr);
System.out.println(arr[0]);
int a=3;
change(a);
System.out.println(a);
change2(arr);
System.out.println(arr[0]);
}
private static void change2(int[] arr) {
arr=new int[5];
arr[0]=100;
return;
}
private static void change(int a) {
a=4;
return;
}
private static void change(int[] arr) {
arr[0]=10;
return;
}
}
- 访问元素:
数组元素可以通过下标访问。 数组下标是基于 0 的, 也就是说, 其范围从 0 开始到
arrayRefVar.length-1结束。 - 示例:查找数组中的最大值、最小值和平均值
public class Test1 {
public static void main(String[] args) {
int[] list=new int[]{1,2,5,8,4,9,6,3,7};
Search(list);
}
public static void Search(int[] list){
int min=list[0];
int max=list[0];
int sum=0;
int num=0;
double average=0;
for(int i=0;i<list.length;i++){
num=list[i];
sum+=num;
if(list[i]>min){
min=list[i];
}
if(list[i]<max){
max=list[i];
}
}
average=(double)sum/list.length;
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
System.out.println("和:"+sum);
System.out.println("平均值:"+average);
}
}
- foreach循环
Java 支持一个简便的 for 循环, 称为 foreach 循环, 即不使用下标变量就可以顺序地遍历整个数组。 例如, 下面的代码就可以显示数组 myList 的所有元素:
for (double e: myList) {
System.out .println(e);
}
此代码可以读作 “ 对 myList 中每个元素 e 进行以下操作” 。 注意, 变量 e 必须声明为与myList 中元素相同的数据类型。通常, foreach 循环的语法为:
for (elementType element: arrayRefVar) {
//Process the element
}
但是, 当需要以其他顺序遍历数组或改变数组中的元素时, 还是必须使用下标变量。
- 示例:分析数字
public class AnalyzeNumbers {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("Enter the number of items:");
int n=scanner.nextInt();
double[] numbers=new double[n];
double sum=0;
System.out.println("Enter the numbers : ");
for(int i=0;i<n;i++){
numbers[i]=scanner.nextDouble();
sum+=numbers[i];
}
double average=sum/n;
int count=0;
for(int i=0;i<n;i++){
if(numbers[i]>average){
count++;
}
}
System.out.println("Average is "+average);
System.out.println("Number of elements above the average is "+count);
}
}
- 示例:一副牌
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
int[] deck=new int[52];
String[] suits={"Spades","Hearts","Diamonds","Clubs"};
String[] ranks={"Ace","1","2","3","4","5","6","7","8",
"9","10","Jack","Queen","King"};
for(int i=0;i<deck.length;i++){
deck[i]=i;
}
for(int i=0;i<deck.length;i++){
int index=(int)(Math.random()*deck.length);
int temp=deck[i];
deck[i]=deck[index];
deck[index]=temp;
/*deck[i]=deck[i]^deck[index];
deck[index]=deck[i]^deck[index];
deck[i]=deck[i]^deck[index];*/
}
for(int i=0;i<4;i++){
String suit=suits[deck[i]/13];
String rank=ranks[deck[i]%13];
System.out.println("Card number "+deck[i]+":"+rank+" of "+suit);
}
}
}
6.2数组的复制
-
自定义复制
使用循环语句逐个地复制数组的元素。 -
Arrays.copyOf()
copyOf(arr,int newlength)
arr:要进行复制的数组。
newlength:int型常量,指复制后的新数组长度。如果新数组的长度大于数组arr的长度,则用0填充;如果复制后的数组长度小于数组arr的长度,则会从数组arr的第一个元素开始截取满足新数组的长度为止。 -
copyOfRang(arr,int fromIndex,int toIndex)
arr:要进行复制的数组。
fromIndex:指定开始复制数组的索引位置。fromIndex必须在0至整个数组的长度之间。新数组包括索引是fromInedx的元素。
toIndex:要复制范围最后索引的位置。可以大于数组的长度。新数组不包括索引是toIndex的元素。 -
示例:统计每个字母出现的次数
在这里插入代码片
6.3可变长参数列表
- 可变长参数与数组
可以把类型相同但个数可变的参数传递给方法。 方法中的参数声明如下:
typeName… parameterName ( 类 型 名 … 参 数 名 )在方法声明中, 指定类型后紧跟着省略号(…)。 只能给方法中指定一个可变长参数, 同时该参数必须是最后一个参数。 任何常规参数必须在它之前。
Java 将可变长参数当成数组对待。 可以将一个数组或数目可变的参数传递给可变长参数。 当用数目可变的参数调用方法时, Java 会创建一个数组并把参数传给它
6.4数组查找与排序
- 冒泡排序
- 选择排序
- 插入排序
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
int[] a={3,5,2,8,6,4,10,7,1,9,15};
BubbleSort(a);
selectSort(a);
insertSort(a);
}
public static void insertSort(int[] a) {
for(int i=0;i<a.length;i++){
/*for(int j=i;j-1>0;j--){
if(a[j-1]>a[j]){
a[j-1]=a[j-1]^a[j];
a[j]=a[j-1]^a[j];
a[j-1]=a[j-1]^a[j];
}
}*/
/*for(int j=i;j-1>0&&a[j-1]>a[j];j--){
a[j-1]=a[j-1]^a[j];
a[j]=a[j-1]^a[j];
a[j-1]=a[j-1]^a[j];
}*/
int e=a[i];
for(int j=i;j>0&&a[j-1]>e;j--){
a[j-1]=e;
}
}
System.out.println(Arrays.toString(a));
}
public static void selectSort(int[] a) {
for(int i=0;i<a.length-1;i++){
for(int j=i+1;j<a.length;j++){
if(a[i]>a[j]){
a[i]=a[i]^a[j];
a[j]=a[i]^a[j];
a[i]=a[i]^a[j];
}
}
}
System.out.println(Arrays.toString(a));
}
public static void BubbleSort(int[] a){
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
a[j]=a[j]^a[j+1];
a[j+1]=a[j]^a[j+1];
a[j]=a[j]^a[j+1];
}
}
}
System.out.println(Arrays.toString(a));
}
}
- 二分查找
public class BinarySearch {
public static void main(String[] args) {
int[] list={1,2,3,4,8,9,10,13,15,18,20,26,35,46,51,78,92};
int i=binarysearch(list, 10);
System.out.println(i);
// System.out.println(java.util.Arrays.binarySearch(list, 10));
}
public static int binarysearch(int[] list,int key){
int low=0;
int high=list.length-1;
while(high>=low){
int mid=(low+high)/2;
if(key<list[mid]){
high=mid-1;
}else if(key>list[mid]){
low=mid+1;
}else if(key==list[mid]){
return mid;
}
}
return -low-1;
}
}
6.5Arrays数组工具类
- java.util.Arrays 类包括各种各样的静态方法, 用于实现数组的排序和査找、 数组的比较和填充数组元素, 以及返回数组的字符串表示。 这些方法都有对所有基本类型的重载方法。
- 可以使用 sort 或者 parallelSort 方法对整个数组或部分数组进行排序。
- 可以采用二分査找法(binarySearch 方法) 在数组中査找关键字。 数组必须提前按升序排列好。
- 可以采用 equals 方法检测两个数组是否相等。 如果它们的内容相同, 那么这两个数组相等。
- 可以使用 fill 方法填充整个数组或部分数组。
- 可以使用 toString 方法来返回一个字符串, 该字符串代表了数组中的所有元素。 这是一个显示数组中所有元素的快捷和简便的方法。
本章小结
1.使用语法 elementType口 arrayRefVar ( 元 素 类 型[]数 组 引 用 变 量 ) 或 elementType arrayRefVar[](元素类型数组引用变量 [] ) 声明一个数组类型的变量。 尽管 elementType
arrayRefVar[]也是合法的, 但还是推荐使用 elementType[] arrayRefVar 风格。
2.不同于基本数据类型变量的声明, 声明数组变量并不会给数组分配任何空间。 数组变量不是基本数据类型变量。 数组变量包含的是对数组的引用。
3.只有创建数组后才能给数组元素賦值。 可以使用 new 操作符创建数组,语法如下:
new elementType[arraySize] (数据类型[ 数组大小 ])。
4.数组中的每个元素都是使用语法 arrayRefVar[index](数组引用变量 [ 下标 ]) 表示的。 下标必须是一个整数或一个整数表达式。
5.创建数组之后, 它的大小就不能改变, 可以使用 arrayRefVar. length 得到数组的大小。 由于数组的下标总是从 0 开始, 所以, 最后一个下标总是 arrayRefVar.length-1。 如果试图引用数组界外的元索, 就会发生越界错误。
6.程序员经常会错误地用下标 1访问数组的第一个元素, 但是, 实际上这个元素的下标应该是 0。 这个错误称为下标过 1 错误( index off-by-one error )。
7.当创建一个数组时, 如果其中的元素的基本数据类型是数值型, 那么賦默认值 0。 字符类型的默认值为 ‘\u0000’ , 布尔类型的默认值为 false。8.Java 有一个称为教组初始化语法( array initializer) 的简捷表达式, 它将数组的声明、 创建和初始化合并为一条语句, 其语法为:元素类型[] 数组引用变量= {valueO.valuel,…valuek}
9.将数组参数传递给方法时, 实际上传递的是数组的引用; 更准确地说, 被调用的方法可以修改调用者的原始数组的元素。
10.如果数组是排好序的, 对于査找数组中的一个元素而言, 二分查找比线性查找更加髙效。
11.选择排序找到列表中最小的数字, 并将其和第一个数字交换。 然后在剩下的数字中找到最小的, 和剩下列表的第一个元素交换, 继续这个步骤, 直到列表中只剩下一个数字。