0
4

More than 3 years have passed since last update.

Java Silver 2章 変数と配列

Last updated at Posted at 2021-09-05

リテラル

リテラル:コード中に直接書き込む値
javaには4つのリテラルがある
・整数(int型が整数のデフォルト)
・浮動小数点数(double型が小数のデフォルト)
・真偽(boolean)
・文字(char)

これ以外のリテラルを明示する場合は下記のルールに従い接頭辞、接尾辞を付ける

public class Main {
    public static void main(String[] args) {
      //整数リテラルの表現方法:10進数以外の表現は下記のルールに従う
      System.out.println(255);         // 10進数(整数値):普通に表記
      System.out.println(0b11111111);  // 2進数:先頭0b
      System.out.println(0377);        // 8進数 :先頭0
      System.out.println(0xff);        // 16進数:先頭0x

      //浮動小数点数リテラルの表現方法
      System.out.println(12.33);       // 10進数(小数):普通に表記
      System.out.println(3e4);         // 指数:3.0 × 10の4乗

      //文字型リテラルの表現方法
      System.out.println('A');         // 1文字:1文字だと''
   System.out.println("Hello");     // 複数文字は""で囲う

      //Unicodeによる文字表現:世界中の言語に数値が割り振ってある
      System.out.println('\u3012');    // u+ 16進数4桁の整数で1文字(0~65535:16bit)
      System.out.println('45662');     // 10進数0~65535までの整数でも可能

      System.out.println(true);        // 論理値:そのまま
    }
}

リテラルはデータ型の宣言、代入なしでコード上で使用できる
変数のように値や状態を保持することができない

変数

変数はリテラルと違い代入により処理結果や値を保持できる
保持するデータ型を明示する必要がある

識別子:変数やメソッドの名前
・予約語(Javaの中で既に定められた特別な名前)は識別子として使用不可
・"_"と"$"以外は使用できない
・数字から始めてはいけない

public class Type {
 public static void main(String[] args){
   byte  b = 10;      //8bit整数
   short s = 20;      //16bit整数
   int   i = 30;      //32bit整数(整数値のデフォルト)
   long  l = 40L;    //64bit整数
   float f = 1.15F;   //32bit単精度浮動小数点数(小数値のデフォルト)
   double  d = 5.78;  //64bit倍精度浮動小数点数
   char  c = 'A';     //単数文字''で囲う
   string s = "string"//複数文字""で囲う
   boolean o = true;
   // final + 定数名  = 初期値
  }
}

変数はデータ型の違いによって2つに大別される
・基本データ型(プリミティブ型):値そのものを扱う
・参照型:値、インスタンスのある場所(データ領域)への参照を扱う

データ型を明示しない場合、整数値、小数値の代入先の変数はそれぞれデフォルトとなる
その際、データ型の容量を超える数値の場合はエラーとなる

桁あふれの検証

public class Ling {
 public static void main(String [] args) {
    int m = 2147483647;
    System.out.println(m + ":int型最大値(32bit)");

    m += 1;
    System.out.println(m + ":+1して桁あふれ");

    long n = 2147483647;
    System.out.println(n + ":lomg型最大値(64bit)");

    n += 1;
    System.out.println(n + ":+1して桁あふれ");
  }
}

実行結果

PS C:\Users\Github\Java\05> java Ling      
2147483647:int型最大値(32bit)
-2147483648:+1して桁あふれ
2147483647:lomg型最大値(64bit)
2147483648:+1して桁あふれ

Int型(最大32bit)Long型(最大64bit)これを超えるとオーバーフローする。
基本情報技術者の時に仕組みだけ知ったが実践してみると面白い

-に転じるのは負の数を補数表現しているからだと思われる

アンダースコア( _ )

桁数の多いリテラルを見やすくする
・リテラルの先頭、末尾は不可
・記号の前後は不可

null

参照先がない状態を表すリテラルの一種であるため、参照型データにしか代入できない
基本データ型に代入するとエラーとなる

変数のスコープ

変数のスオープ(有効範囲)
・ローカル変数:メソッド内で定義した変数(変数のスコープはメソッド内のみ)
・メンバ変数:クラス定義の直下で宣言した変数(基本的にプログラムのどこでも有効)
       修飾子により色々な属性を付加する

ローカル変数の型推論(var)

変数宣言時にデータ型の代わりに"var"を使用すると、右辺の値からデータ型を推論する
変数が初期化されていない状態(空)であったり、nullだとデータ型を特定できない
ローカル変数の宣言でしか使えない(メソッドで宣言する変数)

public class Main {
  //var a = 100;            // コンパイルエラー
  //static var b = 100;     // コンパイルエラー

 public static void main(String[] args) {
    var c = "hello";        // OK
    var d = 100;            // OK
    //var e;                // コンパイルエラー
    //var f = null;         // コンパイルエラー
    final var g = 100;      // OK
    //var final h = 100;    // コンパイルエラー
  }
}

配列の作り方

public class Array {
 public static void main(String[] args) {

  // データ型[] 配列名; 配列宣言

   // 配列の宣言:設計図の段階(何を入れる、何ていう名前の箱?)
   char[] c; //文字データを入れるCという名前の配列の設計図を作製

   // 配列の作成:実際に箱を作る段階(その箱の容量はどのくらい?)
   c = new char[3]; //cという名前の配列設計図(データ型)から実際に文字が3つ入るcという箱を作製 (領域確保)

   // 設計図の名前Cと実際の箱の名前cは必ず一緒になる?



   // 配列の宣言と作成を同時に行う
   int[] i = new int[3];
  //数値を入れるiという名前の箱の設計図に、数字が3つ入る容量を確保した箱を作製

   // やはり設計図の名前iと実際の箱の名前iは必ず一緒になるか…

   // 各要素へ値の代入
   c[0] = 'A'; c[1] = 'B'; c[2] = 'C';       // 各要素へ値の代入
   i[0] = 100; i[1] = 200; i[2] = 300;      
 // iという箱にある3つの区画を指定(配列名[インデックス])して代入


   // 宣言と作成と初期化を同時に行う
   String str[] = {"Welcome ","to ","Java."};
 // strという文字列の入る箱の設計図から3つの区画がある箱を作って、それぞれに初期文字列を設定


   System.out.println("strのサイズ: " + str.length);// 配列の要素数
   System.out.println("c[0]       : " + c[0]);
   System.out.println("i[1]       : " + i[1]);
    }
  }

ここはかなり時間をかけました。
jsやphpでは変数の宣言はクラス外でも可能で
変数の宣言とインスタンスの作成は特に意識しなかったです。

Javaではクラスとオブジェクトを明確に分けるために
new を使い、インスタンス化を明示している印象です。

ただし、変数宣言、作成、初期化を一度に実行する最後の公文では newを使わずにインスタンス化している

設計図:クラス(メソッド・プロパティ)
      ↓
インスタンス:オブジェクト(メソッド・プロパティ)

配列の生成と初期値

public class Main {
  public static void main(String[] args) {
    int i;
    //System.out.println("iの値: " + i); 宣言した時点(設計図段階)ではnullなのでエラー

    int[] array = new int[1];
    System.out.println("array[0]の値 : " + array[0]); 
    //インスタンス化した時点で初期値が割り振られるのでエラーにならない

    //System.out.println("array[0]の値 : " + array[1]); 
  //配列のインデックス[1]は存在しないからエラー
  }
}

Stringオブジェクト

文字列のデータは文字の抜き出しや連結、検索など他のデータ型と比べ多くの機能が必要
他データ型と異なり、変数の宣言では特別なstringクラスをインスタンス化する
→java.lang.string クラス

 string str = "abcde"; //クラスのインスタンス化を明示しない方法
 string str = new string("abcd"); //クラスのインスタンス化を明示する方法

クラスのコンストラクタを使用する時以外は、new キーワードを使わない方がメモリ効率が良い

 stringクラスのメソッド
スキャン 2021-09-13 10.42.JPG

多次元配列

public class Multi {
  public static void main(String[] args) {
     //基本的には普通の配列と一緒
     int[][] array;  //設計図の作成
     array = new int[3][4];  //設計図から容量3×4の箱を作成(jacaではint型初期値は0)

     //int[][] array = new int[3][4]; ←二つを省略してこのようにも書ける

     array[0][0] = 100; //インデックスを指定して代入
     array[0][3] = 200;  //インデックスを指定して代入

     System.out.println("array[0][0]の値 : " + array[0][0]);
     System.out.println("array[0][3]の値 : " + array[0][3]);

     //設計図の作成、配列の作成、値の代入を同時に実行
     int[][] array2 = {
           {10, 20, 30, 40},
           {50, 60, 70, 80},
           {100, 200, 300, 400}
           };
     System.out.println("array2[0][0]の値 : " + array[0][0]);
     System.out.println("array2[0][3]の値 : " + array[0][3]);      
  }
}

多次元配列のイメージはX,Y,Zのグラフをイメージすると分かりやすい。

要素数が不揃いな多次元配列

public class Multi2 {
 public static void main(String[] args) {

  //array配列のインスタンス作成
  //数値の入る箱のx軸を3つに設定、Y軸は未設定
    int[][] array = new int[3][];

  //array配列のインデックス[0]に対し
    array[0] = new int[3]; //X軸[0]にY軸3つの区画を割り当てる
    array[1] = new int[5]; //...5つ
    array[2] = new int[2]; //...2つ
  //この時点で配列arrayのX,Y区画数が決定  →  インスタンスとして機能する

  // 上記を一括で実行
    int[][] array2 = {
               {10, 20, 30},
               {50, 60, 70, 80, 90},
               {100, 200}
            };

     System.out.println("array2[0][0]の値 : " + array[0][0]);
     System.out.println("array2[1][4]の値 : " + array[1][4]);
    }
}

要素数のふぞろいな多次元配列のインスタンス化はややこしい。
便宜的にX,Yと表現していますが僕の中のイメージです。

1:配列X軸に対して new を明示し要素数を指定してインスタンス化する

2:要素数を指定した配列のx軸に対して、それぞれ new を明示し要素数を指定する(Y軸)

ややこしいのは 1でインスタンス化(領域確保)した要素はX軸のみで
2でインスタンスしたX軸要素に対して、1次元配列と同じようにY軸のインスタンス化を行う事

完全に僕のイメージです

多次元配列の作成 エラーパターン

public class Multi3 {
    public static void main(String[] args) {
      int[][] a1 = new int[2][];        // OK
      //int[][] a2 = new int[][2];      // コンパイルエラー
      //int[] a3 = new int[2]{ };       // コンパイルエラー
      //int[] a4 = new int[2]{10, 20};  // コンパイルエラー
      int[] a5 = new int[]{10, 20};     // OK
      int[] a6 = { };                   // OK
      int[][] a7 = { };                 // OK
      int[][] a8 = new int[][]{ };      // OK
      //var a9 = {10, 20};              // コンパイルエラー
      var a10 = new int[]{10, 20};      // OK
    }
  }

行数と理由
1.X軸の配列要素のみインスタンス化は可能
2.Y軸の配列要素のみのインスタンス化はできない
3.4:要素数指定と初期化を同時に行えない。
 3.一次元配列の要素数を[2]で指定。{}で初期化を同時に行っている。
 4.一次元配列の要素数を[2]で指定。{10,20}で初期化を同時に行っている。
5.一次元配列の要素数は指定せず{10,20}で初期は可能。
 int[] a5 = {10,20} と同義
6.同じく要素数を指定せず{}(null)で初期化は可能
7.同じく二次元配列の要素は指定せず{}(null)で初期化は可能(初期化しているのはX軸のみ)
8. 7と同義
9.配列の初期化ではデータ型を明示しないと予測する事ができないため
10.データ型が明示されているためOK

コマンドライン引数

public class Comand {
    //引数はString[]配列に格納されargsに引き渡される
    public static void main(String[] args) {
      System.out.println(args[0]);
      System.out.println(args[1]);
      System.out.println(args[2]);
      System.out.println(args[1] + args[2]);
    }
  }

上記のComandクラスをターミナルで実行する際、一緒に引数を指定する

naito
20
50
2050  ←String型なので足し算されない

main()メソッドの引数String[] argsの使い方がわかった

第2章感想

配列の宣言、作成、初期化の書き方ルールが複雑なので問題を解いて慣れる必要がある
JavascriptやPHPでは何となくでできていた事もJavaでは厳密にルールに沿って記載しなければいけない。

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4