07-一维数组

07-一维数组

  • 7.1 引言

    • 单个的数组变量可以引用一个大的数据集合。
  • 7.2 数组的基础知识

    一旦数组被创建,他的大小是固定的。使用一个数组引用变量和下标来访问数组中的元素。

    • 7.2.1 声明数组变量
      • 为了在程序中使用数组,必须声明一个引用数组的变量,并指明数组的元素类型。下卖弄是声明数组变量的语法:
        elementType[] arrayRefVar;
        //或者
        elementType arrayRefVar[];//是允许这样的,但是不是最好的方式
        
      • elementType可以是任意数据类型,但是数组中所有的元素都必须具有相同的数据类型。
      • 也可以用elementType arrayRefVar[]声明数组变量。这种来自c/c++语言的风格被Java采纳以适用于c/c++程序员。推荐使用elementType[] arrayRefVar。
    • 7.2.2 创建数组
      • 不同于声明基本数据类型变量,声明一个数组变量时并不给数组分配任何内存空间。它只是创建一个对数组的引用的存储位置。如果变量不包含对数组的引用,那么这个变量的值为null。除非数组已经被创建,否则不能给他分配任何元素。声明数组变量之后,可以使用下面的语法用new操作符创建数组,并且将它的引用赋给一个变量:
        arrayRefVar = new elementType[arraySize];
        
      • 这条语句做了两件事:
        • 1、使用new elementType[arraySize]创建了一个数组;
        • 2、把这个新创建的数组的引用赋值给变量arraySize。
      • 声明一个数组变量、创建数组、将数组引用赋值给变量这三个步骤可以合并在一条语句里。
        elementType[] arrayRefVar = new elementType[arraySize];
        //或者
        elementType arrayRefVar[] = new elementType[arraySize];
        
      • 一个数组变量看起来似乎是存储了一个数组,但实际上他存储的是指向数组的引用。严格的讲,一个数组变量和一个数组是不同的,但多数情况下他们的差别是可以忽略的。因此,为了简化,通常常可以说myList是一个数组,而不用更长的陈述:myList是一个含有double型元素数组的引用变量。
    • 7.2.3 数组大小和默认值
      • 当给数组分配空间时,必须指定该数组能够存储的元素个数,从而确定数组大小。创建数组之后就不能再修改它的大小了。可以使用arrayRefVar.length得到数组的大小。
      • 当创建数组后,他的元素呗赋予默认值,数值型基本数据类型的默认值为0,char型的默认值为‘\u0000’,boolean型的默认值为false。
    • 7.2.4 访问数组元素
      • 数组元素可以通过下标访问。数组下标是基于0的,也就是说,其范围从0开始到arrayRefVar.length-1结束。数组中的每个元素都可以使用下面的语法表示,称为下标变量:
        arrayRefVar[index];
        
    • 7.2.5 数组初始化简写方式
      • Java有一个简捷的标记,称作数组初始化简写方式,他使用下面的语法将声明数组、创建数组和初始化数组结合到一条语句中:
        elementType[] arrayRefVar = {value0,value1,...,valuek};
        
      • 数组初始化简写方式中不使用操作符new。使用数组初始化简写方式时,必须将声明、创建和初始化数组都放在一条语句中。
    • 7.2.6 处理数组
      • 处理数组元素时,经常会用到for循环,理由如下:
        • 数组中所有元素都是同一类型的。可以使用循环以同样的方式反复处理这些元素。
        • 由于数组的大小是已知的,所以很自然的就使用for循环。
      • 1、使用输入值初始化数组
        double[] myList = new double[4];
                java.util.Scanner input = new java.util.Scanner(System.in);
                System.out.print("Enter " + myList.length + " values: ");
                for (int i = 0;i < myList.length;i++)
                    myList[i] = input.nextDouble();
        
      • 2、使用随机数初始化数组
        for (int i = 0;i < myList.length;i++){
                    myList[i] = Math.random() * 100;
                }
        
      • 3、显示数组
        char[] city = {'D','a','l','l','a','s'};
                System.out.println(city);
        
      • 4、对所有元素求和
        double total = 0;
                for (int i = 0;i < myList.length;i++){
                    total += myList[i];
                }
        
      • 5、找出最大元素
        double max = myList[0];
                for (int i = 0;i < myList.length;i++){
                    if (myList[i] > max)max = myList[i];
                }
        
      • 6、找出最大元素的最小下标值
        double max = myList[0];
                int indexOfMax = 0;
                for (int i = 1;i < myList.length;i++){
                    max = myList[i];
                    indexOfMax = 1;
                }
        
      • 7、随机打乱
        for (int i = 0;i < myList.length - 1;i++){
                    int j = (int)(Math.random() * myList.length);
                    double temp = myList[i];
                    myList[i] = myList[j];
                    myList[j] = temp;
                }
        
      • 8、移动元素
        double temp = myList[0];
                for (int i = 1;i < myList.length;i++){
                    myList[i - 1] = myList[i];
                }
                myList[myList.length - 1] = temp;
        
      • 9、简化编码
        String[] months = {"January","Februry",....,"December"};
                System.out.print("Enter a month number (1 to 12): ");
                int monthNumber = input.nextInt();
                System.out.println("The month is " + months[monthNumber - 1]);
        
    • 7.2.7 foreach循环
      • Java支持一个简便的for循环,称为foreach循环,即不使用下标变量就可以顺序的遍历整个数组。下面的代码就可以显示数组myList的所有元素:
        for(double e : myList){
        	Syetem.out.println(e)
        }
        
      • foreachde的语法是:
        for(elementType element: arrayRefVar){
        //Process the element
        }
        
  • 7.3 示例学习:分析数字

    • 编写一个程序,找到大于平均值的项的数目。
      package chapter06;
      
      public class AnalyzeNumbers {
          public static void main(String[] args){
              java.util.Scanner input = new java.util.Scanner(System.in);
              System.out.print("Enter the number of items: ");
              int n = input.nextInt();
              double[] numbers = new double[n];
              double sum = 0;
              
              System.out.print("Enter the numbers : ");
              for (int i = 0;i < n;i++){
                  numbers[i] = input.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);
          }
      }
      
      
  • 7.4 示例学习:一副牌

    package chapter06;
    
    public class DeckOfCards {
        public static void main(String[] args){
            int[] deck = new int[52];
            String[] suits = {"Spads","Hearts","Diamonds","clubs"};
            String[] ranks = {"Ace","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;
            }
            
            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);
            }
        }
    }
    
    
  • 7.5 复制数组

    • 要将一个数组中的内容复制到另外一个数组中,需要将数组的每个元素复制到另外一个数组中。
      list2 = list1
      
    • 上面的语句并不能将list1引用的数组内容复制到list2,而只是将list1的引用值复制给了list2.在这条语句之后,list1和list2都指向同一个数组。list2原先所引用的数组不能再引用,它就变成了垃圾,会被Java虚拟机自动收回(这个过程称为垃圾回收)。
    • 复制数组有三种方法:
      • 1、使用循环语句逐个的赋值数组的元素;
      • 2、使用System类中的静态方法arraycopy;
        • arraycopy的语法是:
          arraycopy(sourceArray,srcPos,targeArray,tarPos,length);
          
        • 参数srcPos和tarPos分别表示在源数组sourceArray和目标数组targetArray中的起始位置。从sourceArray复制到targetArray中的元素个数由参数length指定。
        • arraycopy方法没有给目标数组分配内存空间。复制前必须创建目标数组以及分配给他的内存空间。复制完成后,sourceArray和targetArray具有相同的内容,但占有独立的内存空间。
      • 3、使用clone方法赋值数组。
  • 7.6 将数组传递给方法

    • 当一个数组传递给方法时,数组的引用被传给方法。
    • 和方法传递基本数据类型一样,也可以给方法传递数组。
      public static void printArray(int[] array){
      	for(int i = 0;i < array.length;i++){
      		System.out.print(array[i] + " ");
      	}
      }
      
    • 使用下述语法创建数组:
      new elementType[]{value0,value1,...,valuek};
      
    • 该数组没有显式的引用变量,这样的数组称为匿名函数。
    • Java使用按值传递的方式将实参传递给方法。传递剧本数据类型变量的值与传递数组值有很大的不同:
      • 对于基本数据类型参数,传递的是实参的值;
      • 对于数组类型参数,参数值是数组的引用,给方法传递的是这个引用。从语义上来讲,最好的描述为传递共享信息,即方法中的数组和传递的数组是一样的。因此,如果改变方法中的数组,将会看到方法外的数组也改变了。
        package chapter06;
        
        public class TestPassArray {
            public static void main(String[]  args){
                int[] a = {1,2};
                
                System.out.println("Before invoking swap");
                System.out.println("array is {" + a[0] + ", " + a[1] + "}");
                swap(a[0],a[1]);
                System.out.println("After invoking swap");
                System.out.println("array is {" + a[0] + ", " + a[1] + "}");
            }
            public static void swap(int n1,int n2){
                int temp = n1;
                n1 = n2;
                n2 = temp;
            }
            public static void swapFirstTwoInArray(int[] array){
                int temp = array[0];
                array[0] = array[1];
                array[1] = temp;
            }
        }
        
        
  • 7.7 方法返回数组

    • 当方法返回一个数组时,数组的引用被返回。
  • 7.8 示例学习:统计每个字母出现的次数

    package chapter06;
    
    public class CountLettersInArray {
        public static void main(String[] args){
            char[] chars = createArray();
            
            System.out.println("The lowercase letters are: ");
            displayArray(chars);
            
            int[] counts = countLetters(chars);
            
            System.out.println();
            System.out.println("The occurrences of each letter are: ");
            displayCounts(counts);
        }
        public static char[] createArray(){
            char[] chars = new char[100];
            for (int i = 0;i < chars.length;i++)
                chars[i] = RandomCharacter.getRandomLowerCaseLetter();
            return chars;
        }
        public static void displayArray(char[] chars){
            for (int i = 0;i < chars.length;i++){
                if ((i + 1) % 20 == 0)
                    System.out.println(chars[i]);
                else 
                    System.out.println(chars[i] + " ");
            }
        }
        public static int[] countLetters(char[] chars){
            int[] counts = new int[26];
            for (int i = 0;i < chars.length;i++)
                counts[chars[i] - 'a']++;
            return counts;
        }
        public static void displayCounts(int[] counts){
            for (int i = 0;i < counts.length;i++){
                if ((i + 1) % 10 == 0)
                    System.out.println(counts[i] + " " + (char)(i + 'a'));
                else 
                    System.out.println(counts[i] + " " + (char)(i + 'a') + " ");
            }
        }
    }
    
    
  • 7.9 可变长参数列表

    • 具有同样类型的数目可变的参数可以传递给方法,并将作为数组对待。方法中的参数声明如下:
      typeName...patameterName(类型名...参数名)
      
    • 在方法声明中,指定类型后紧跟着省略号(…)。只能个方法中指定一个可变长参数,同时该参数必须是最后一个参数。任何常规参数必须在他之前。
    • Java将可变长参数当成数组对待。
      package chapter06;
      
      public class VarArgsDemo {
          public static void main(String[] args){
              
          }
          public static void printMax(double...numbers){
              if (numbers.length == 0){
                  System.out.println("No argument passed");
                  return;
              }
              
              double result = numbers[0];
              
              for (int i = 1;i < numbers.length;i++)
                  if (numbers[i] > result)
                      result = numbers[i];
                  
               System.out.println("The max value is " + result);
          }
      }
      
      
  • 7.10 数组的查找

    • 7.10.1 线性查找法
      package chapter06;
      
      public class LineearSearch {
          public static int linearSearch(int[] list,int key){
              for (int i = 0;i < list.length;i++){
                  if (key == list[i])
                      return i;
              }
              return -1;
          }
      }
      
      
    • 7.10.2 二分查找法
      package chapter06;
      
      public class BinarySearch {
          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])
                      return mid;
                  else 
                      low = mid + 1;
              }
              return -low + 1;
          }
      }
      
      
    • 二分查找法的前提是列表必须以升序排好序了。
  • 7.11 数组的排序

    package chapter06;
    
    public class SelectionSort {
        public static void selectiongSort(double[] list){
            for (int i = 0;i < list.length;i++){
                double currentMin = list[i];
                int currentMinIndex = 1;
                
                for (int j = i + 1;j < list.length;j++){
                    if (currentMin > list[j]){
                        currentMin = list[j];
                        currentMinIndex = j;
                    }
                }
                if (currentMin != 1){
                    list[currentMinIndex] =list[i];
                    list[i] = currentMin;
                }
            }
        }
    }
    
    
  • 7.12 Arrays类

    • java.util.Arrays类包含一些使用的方法用于常见的数组操作,比如排序和查找。
    • 可以使用sort或者parrallelSort方法对整个数组或部分数组进行排序。
    • 可以调用sort(number)对整个数组numbers排序。可以调用sort(chars,1,3)对从chars[1]到chars[3-1]的部分数组进行排序。如果你的计算机有多个处理器,那么parallelSort将更加高效。
      		double[] numbers = {6.0,4.4,1.9,2.9,3.4,3.5};
              java.util.Arrays.sort(numbers);
              java.util.Arrays.parallelSort(numbers);
              
              char[] chars = {'a','A','4','F','D','P'};
              java.util.Arrays.sort(chars,1,3);
              java.util.Arrays.parallelSort(chars,1,3);
      
    • 可以采用二分查找法(binarySearch方法)在数组中查找关键字。如果数组中不存在关键字,方法返回-(insertIndex+1)。
      		int[] list = {2,4,7,10,11,45,50,59,60,66,69,70,79};
              System.out.println("1. Index is " + java.util.Arrays.binarySearch(list,11));
              System.out.println("2. Index is " + java.util.Arrays.binarySearch(list,12));
              
              char[] chars1 = {'a','c','g','x','y','z'};
              System.out.println("3.Index is " + java.util.Arrays.binarySearch(chars,'a'));
              System.out.println("4.Index is " + java.util.Arrays.binarySearch(chars,'t'));
      
    • 可以采用equals方法检测两个数组是否严格相等。
      		int[] list1 = {2,4,7,10};
              int[] list2 = {2,4,7,10};
              int[] list3 = {4,2,7,10};
              System.out.println(java.util.Arrays.equals(list1,list2));//true
              System.out.println(java.util.Arrays.equals(list2,list3));//false
      
    • 可以使用fill方法填充整个数组或部分数组。
      int[] list1 = {2,4,7,10};
              int[] list2 = {2,4,7,7,7,10};
              java.util.Arrays.fill(list1,5);
              java.util.Arrays.fill(list2,1,5,8);
      
    • 可以使用toString方法来返回一个字符串,该字符串代表了数组中的所有元素。
      int[] list3 = {2,4,7,10};
              System.out.println(java.util.Arrays.toString(list));
      
  • 7.13 命令行参数

    main方法的生命有点特殊,他具有String[]类型参数args。很明显,参数args是一个字符串数组。main方法就像一个带参数的普通方法。可以通过传递实参来调用一个普通方法。当然也是可以给main传递参数的。

    • 7.13.1 向main方法传递字符串
      • 运行程序时,可以从命令行给main方法传递字符串参数。例如,爱你的命令行用三个字符串arg0、arg1、arg2启动程序TestMain:
        java TestMain arg0 arg1 arg2
        
      • 其中,参数arg0、arg1、arg2都是字符串,但是在命令行中出现时,不需要放在双引号中。这些字符串用空格分隔。如果字符串包含空格,那就必须使用双引号括住。
      • 当调用main方法时,Java解释器会创建一个数组存储命令行参数,然后将该数组的引用传递给args。例如,乳沟调用具有n个参数的程序,Java解释器创建一个如下所示的数组:
        args = new String[n];
        
      • 如果运行程序时没有传递字符串,那么使用new String[0]创建数组。在这种情况下,哎数组是长度为0的空数组。args是对这个空数组的引用。因此,args不是null,args.length为0。
    • 7.13.2 示例学习:计算器
      package chapter06;
      
      public class Calculator {
          public static void main(String[] args){
              if (args.length != 3){
                  System.out.println("Usage:java Calculator operand1 operator operand2");
                  System.exit(1);
              }
              
              int result = 0;
              
              switch (args[1].charAt(0)){
                  case '+':result = Integer.parseInt(args[0]) + Integer.parseInt(args[2]);break;
                  case '-':result = Integer.parseInt(args[0]) - Integer.parseInt(args[2]);break;
                  case '.':result = Integer.parseInt(args[0]) * Integer.parseInt(args[2]);break;
                  case '/':result = Integer.parseInt(args[0]) / Integer.parseInt(args[2]);break;
              }
              System.out.println(args[0] + ' ' + args[1] + ' ' + args[2] + " = " + result);
          }
      }
      
      
      • 我们使用.符号用于乘法,而不是通常的符号。原因是当符号用于命令行时表示当前目录下的所有文件。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值