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);
          }
      }
      
      
      • 我們使用.符號用于乘法,而不是通常的符號。原因是當符號用于命令行時表示當前目錄下的所有文件。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375