Java笔记(11)-数组和枚举,int [] a,int a[],创建数组,数组遍历,复制数组,排序和二分法,枚举


问渠哪得清如许?为有源头活水来。—-朱熹《观书有感二首》


数组和枚举

1 创建数组

数组是相同类型变量按顺序组成的一种复合数据类型,称这些相同的变量为数组的元素或单元。数组通过数组名加索引来使用数组的元素。
数组属于引用型变量,创建数组需要经过声明数组为数组分配变量这两个步骤。

1.1 声明数组

一维数组的声明,二三维同理。

数组元素类型  数组名[];
数组元素类型[]  数组名;

例如:

float boy[];
float[] boy;
char cat[][];

数组的元素类型可以是 Java 的任何一种类型。
Dog 是一个类

Dog tom[]  // Tom的元素存放Dog对象的引用

与C或C++不同,Java 不允许在声明数组中的方括号内指定数组元素的个数。

int a[5]; //错误
int [5] a; //错误

1.2 为数组分配元素

为数组分配元素的格式如下:

数组名 = new 数组元素的类型[数组元素的个数];

boy = new float[4];

int size = 5;
boy = new float[size];

数组 boy 获得了4个用来存放 float 类型数据的变量。
数组变量 boy 中存放着这些元素的首地址,该地址称作数组的引用,这样数组就可以通过索引操作这些内存单元。
数组属于引用型变量,数组变量中存放着数组的元素的首地址,通过数组变量的名字加索引使用数组的元素。

Java笔记(11)-数组和枚举,int [] a,int a[],创建数组,数组遍历,复制数组,排序和二分法,枚举_第1张图片

声明数组和创建数组可以一起完成:

float [] boy = new float[4];
int [] mytwo = new int[3][4] // 3个长度为4的一维数组组成

Java 采用“数组的数组”来声明多为数组,一个二维数组是由若干个一维数组组成的

1.3 防止索引越界

float [] boy = new float[6];

数组有6个元素,那么索引到5为止,boy[6] 能编译通过,但运行时会发生 ArrayIndexOutOfBoundsException异常

1.4 length 的使用

float [] a = new float[6];
int [][] b = new [3][6];

a.length 的值为 6 ,而 b.length 的值为 3 (含一维数组的个数).

1.5 数组的初始化

创建数组后,系统默认每个元素值为 0 ,如 float 型是 0.0。
也可以声明的同时赋值:

int [] boy = {12,23,434,54,656,776,68};  //boy[7]

用一维数组初始化二维数组:

int [][] a = {{1},{2,3,4},{5,6,7,8},{9}}; //a[4][]

这些一维数组的长度不尽相同

1.6 数组的引用

public class Test {
    public static void main(String[] args) {
        int[] one = { 1, 2, 3, 4, 5 };
        String[] str = { "文", "武", "智", "谋", "德", "孝" };
        int[][] two = { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };
        char[] ch = { '国', '庆', '节', '快', '乐' };

        System.out.println("数组one的长度:" + one.length);
        System.out.println("数组str的长度:" + str.length);
        System.out.println("数组two的长度:" + two.length);
        System.out.println("数组ch的长度:" + ch.length);

        System.out.println("数组one的引用" + one);
        System.out.println("数组str的引用" + str);
        System.out.println("数组two的引用" + two);

        System.out.println("数组ch的引用" + ch);// 并置操作 右边的内容接在左边的内容之后以形成一个新的位矢量.
        System.out.println(ch); // 对于char数组,输出全部元素

        System.out.println("one[0]:" + one[0]);
        System.out.println("str[5]:" + str[5]);
        System.out.println("ch[3]:" + ch[3]);

        System.out.println("two[0][0]=" + two[0][0] + ",two[0][1]=" + two[0][1] + ",two[0][2]=" + two[0][2]);
        System.out.println("two[1][0]=" + two[1][0] + ",two[1][1]=" + two[1][1]);
        System.out.println("two[2][0]=" + two[2][0] + ",two[2][1]=" + two[2][1] + ",two[2][2]=" + two[2][2]
                + ",two[2][3]=" + two[2][3]);
    }
}
数组one的长度:5
数组str的长度:6
数组two的长度:3
数组ch的长度:5
数组one的引用[I@15db9742
数组str的引用[Ljava.lang.String;@6d06d69c
数组two的引用[[I@7852e922
数组ch的引用[C@4e25154f
国庆节快乐
one[0]:1
str[5]:孝
ch[3]:快
two[0][0]=1,two[0][1]=2,two[0][2]=3
two[1][0]=4,two[1][1]=5
two[2][0]=6,two[2][1]=7,two[2][2]=8,two[2][3]=9

2 遍历数组

2.1 基于循环语句的遍历

这种形式的 for 语句类似“for each”语句,可以翻译下面的语句为“对于循环变量依次取数组的每一个元素的值”。

for(声明循环变量: 数组的名字){
......
}

声明的循环变量的类型必须与数组的类型相同。

public class TestFoeach {
    public static void main(String[] args) {
        int[] a = { 1, 2, 3, 4 };

        for (int n = 0; n < a.length; n++) { // 传统方式
            System.out.print(a[n]);
        }

        for (int i : a) { // 非传统方式
            System.out.print(i);
        }
    }
}

2.2 使用 toString() 方法遍历

一个简单的输出数组元素值的方法。让 Arrays 类调用

public static String toString(int [] a)

方法,可以得到参数指定的一维数组,格式如下

[ a[0],a[1],a[3],....a[a.length-1] ]

例如:

import java.util.Arrays;
public class Test2 {
    public static void main(String[] args) {
        int[] one = { 1, 2, 3, 4, 5 };
        System.out.println(Arrays.toString(one));
    }
}
[1, 2, 3, 4, 5]

3 复制数组

数组属于引用类型。也就是说,如果两个类型相同的数组具有相同的引用,那么它们就有完全相同的元素。

int [] a = {1,2}, b[];

如果执行

b = a;

那么 a 和 b 的值相同,即 a 的引用与 b 的引用相同。这样,a[0] 和 b[0] 是相同的内存空间。
但是数组之间进行引用赋值的方式,改变数组中一个元素的值,另一个数组的对应的值也会改变

import java.util.Arrays;

public class TestCopy {
    public static void main(String[] args) {
        int a []= { 1, 2, 3, 4, 5 },b[];
        b=a;
        System.out.println(Arrays.toString(b));
        a[0]=5;// a数组改变一个元素的值
        System.out.println(Arrays.toString(b));     
    };
}
[1, 2, 3, 4, 5]
[5, 2, 3, 4, 5]

3.1 arraycopy 方法

数组之间不影响的话,一个方法就是利用循环语句把一个数组的元素的值分别赋值给另一个数组中相应的元素(C 语言中常用)。下面是 Java 中的更简练的数组之间的快速复制 :

 public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

可以将数组 src 从索引 srcPos 开始后的 length 个元素中的数据复制到数组 dest 中,即将数组 src 中的索引值从 srcPos 到 srcPos+length-1 的元素中的数据复制到数组 dest 中,数组 dest 从第destPos 元素开始存放这些数据。如果数组 dest 存不下,就会有异常。

public class Testarraycopy {
    public static void main(String args[]) {
        char[] a = { 'A', 'B', 'C', 'D', 'E', 'F' }, b = { '1', '2', '3', '4', '5', '6' };
        int[] c = { -1, -2, -3, -4, -5, -6 }, d = { 10, 20, 30, 40, 50, 60 };

        System.arraycopy(a, 0, b, 0, a.length);
        System.arraycopy(c, 2, d, 2, c.length - 3);

        System.out.println("数组 a 的各个元素中的值:");
        System.out.println(Arrays.toString(a));
        System.out.println("数组 b 的各个元素中的值:");
        System.out.println(Arrays.toString(b));
        System.out.println("数组 c 的各个元素中的值:");
        System.out.println(Arrays.toString(c));
        System.out.println("数组 d 的各个元素中的值:");
        System.out.println(Arrays.toString(d));
    }
}
数组 a 的各个元素中的值:
[A, B, C, D, E, F]
数组 b 的各个元素中的值:
[A, B, C, D, E, F]
数组 c 的各个元素中的值:
[-1, -2, -3, -4, -5, -6]
数组 d 的各个元素中的值:
[10, 20, -3, -4, -5, 60]

3.2 copyOf 和 copyOfRange() 方法

上面的 arraycopy 方法有一个缺点,就是事先必须创建 copyArray 指定的数组。JDK1.6后,Java 又提供了一个 copyOf 和 copyRange() 方法。例如 Arrays 类调用:

public static int[] copyOf(int[] original, int newLength)

把 original 指定的数组从索引 0 到开始的 newLength 个元素复制到新数组中,并返回新数组。

int [] a = {100,,200,300,400};
int [] b = Arrays.copyOf(a,5);

那么

b [] = {100,,200,300,4000};

b[4] 取默认值 0。


另外一个方法,可以把数组中的部分元素的值复制到另一个数组中,例如:

 public static int[] copyOfRange(int[] original, int from, int to)

把 original 指定的数组中从 form 至 to-1 的元素复制到一个新的数组中,并返回这个数组,即新数组的长度是 to - from。如果 to 的值大于数组 original 的长度,新数组第 original.length - from 索引开始取默认值。例如:

int [] a = {100,,200,300,400500,600};
int [] b =Arrays.copyOfRange(a,2,5);

那么

b[] = {300,400,500};

下面是使用 copyOf() 和 copyOfRange() 方法复制数组

import java.util.Arrays;

public class TestcopyOf {
    public static void main(String args[]) {
        int[] a = { 11, 22, 33, 44, 55 }, b, c, d;

        b = Arrays.copyOf(a, 8);

        System.out.println("数组 a 的各个元素中的值:");
        System.out.println(Arrays.toString(a));

        System.out.println("数组 b 的各个元素中的值:");
        System.out.println(Arrays.toString(b));

        c = Arrays.copyOfRange(a, 3, 5);

        System.out.println("数组 c 的各个元素中的值:");
        System.out.println(Arrays.toString(c));

        d = Arrays.copyOfRange(a, 1, 7);

        System.out.println("数组 d 的各个元素中的值:");
        System.out.println(Arrays.toString(d));
    }
}
数组 a 的各个元素中的值:
[11, 22, 33, 44, 55]
数组 b 的各个元素中的值:
[11, 22, 33, 44, 55, 0, 0, 0]
数组 c 的各个元素中的值:
[44, 55]
数组 d 的各个元素中的值:
[22, 33, 44, 55, 0, 0]

4 排序和二分法查找

可以使用循环语句对数组排序,也可以使用循环语句查找某个数据是否在一个排序的数组中。
Arrays 类调用

public static void sort(int[] a)

可以把参数 a 指定的 int 型数组按升序排列。

Arrays 类调用

 public static void sort(int[] a, int fromIndex, int toIndex)

可以把参数 a 指定的 int 型数组中索引 fromIndex 至 toIndex-1 按升序排列。

Arrays 类调用(二分法)

 public static int binarySearch(int[] a, int key)

方法判断 key 是否和数组 a 的某个值相同,其中数组 a 必须是事先排序的数组。查找相同则返回该元素的索引,否则返回一个负数。

import java.util.Arrays;
import java.util.Scanner;
public class Testsort {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        int[] a = { 12, 34, 9, 23, 45, 6, 45, 90, 123, 19, 34 };
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));

        System.out.println("输入整数,程序判断该整数是否在数组中:");
        while (scanner.hasNextInt()) {// 从键盘中输入int型数据
            int number = scanner.nextInt();
            int index = Arrays.binarySearch(a, number);
            if (index >= 0) {
                System.out.println(number + "和数组中索引为" + index + "的元素值相同");
            } else {
                System.out.println(number + "不与数组中任何元素值相同");
            }
            System.out.println("是否继续输入整数?输入任何非整数即可结束");
        }
    }
}
[6, 9, 12, 19, 23, 34, 34, 45, 45, 90, 123]
输入整数,程序判断该整数是否在数组中:
6
6和数组中索引为0的元素值相同
是否继续输入整数?输入任何非整数即可结束
4
4不与数组中任何元素值相同
是否继续输入整数?输入任何非整数即可结束
123
123和数组中索引为10的元素值相同
是否继续输入整数?输入任何非整数即可结束

5 枚举

5.1 枚举类型的定义

JDK1.5 引入了一种新的数据类型: 枚举类型
枚举类型的定义包括枚举声明和枚举体,语法如下:

enum 枚举体
{常量列表
}

常量要符合标识符的规定,即由字母、下划线、美元符号和数字组成,并且第一个字符不能是数组。

enum Season
{ spring,summer,autumn,winter
}

声明了名字为 Season 的枚举类型,该枚举体类型有 4 个常量。

5.2 枚举变量

声明一个枚举类型后,可以用枚举类型名声明一个枚举变量,例如:

Season x;

声明一个枚举变量x。枚举变量 x 只能取值枚举类型的常量。通过使用枚举名和“.”运算符获得枚举类型中的变量,例如:

x = Season.spring;

可以在一个 Java 源文件中只声明定义枚举类型,然后保存该源文件,然后单独编译这个源文件得到的枚举类型的字节码文件,那么该字节码可以被其他源文件中的类使用。

例如:

Weekday.java

public enum Weekday {
   星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日
}

Testenmu.java

public class Testenmu {
    public static void main(String args[]) {
        Weekday_enmu x = Weekday_enmu.星期日;
        if (x == Weekday_enmu.星期日) {
            System.out.println(x);
            System.out.println("今天我休息");
        }
    }
}
星期日
今天我休息

5.3 枚举类型与 for 语句和switch 语句

  1. 使用 for 语句遍历枚举常量
    枚举类型使用枚举类型的名字.values();返回一个数组。

Weekday.java

public enum Weekday {
   星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日
}
WeekDay [] a = WeekDay.values();

那么 a[ ] 为 星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日。

下面的例子,输出从红、黄、蓝 3 种颜色中取出两种不同颜色的排列。

enum Color {
  红,黄,绿
}
public class Testvalues {
   public static void main(String args[]) {
      for(Color a:Color.values()) { //遍历红,黄,绿
         for(Color b:Color.values()) {
            if(a!=b) // 当不同时输出
              System.out.print(a+","+b+"|");
         }
      }
    }
} 
红,黄|红,绿|黄,红|黄,绿|绿,红|绿,黄|
  1. switch 语句中使用枚举变量
    下面的例子中,结合 for 语句和 switch 语句显示了 5 种水果中的部分水果的价格,其中 for 语句和 switch 语句都使用了枚举类型。
enum Fruit {
    苹果, 梨, 香蕉, 西瓜, 芒果
}

public class Example7_8 {
    public static void main(String args[]) {
        double price = 0;
        boolean show = false;
        for (Fruit fruit : Fruit.values()) {
            switch (fruit) {
            case 苹果:
                price = 1.5;
                show = true;
                break;
            case 芒果:
                price = 6.8;
                show = true;
                break;
            case 香蕉:
                price = 2.8;
                show = true;
                break;
            default:
                show = false;
            }
            if (show) {
                System.out.println(fruit + "500克的价格:" + price + "元");
            }
        }
    }
}
苹果500克的价格:1.5元
香蕉500克的价格:2.8元
芒果500克的价格:6.8元

你可能感兴趣的:(Java)