2014年12月11日木曜日

Java基礎(1章~7章メソッドまで)

Javaの特徴

開発ツールが無料

オブジェクト指向

一度作ったプログラムはどこでも動く(Write Once, Run Anywhere)
※Javaを動かすにはJRE(Java Runtime Envelopement)が必要


開発準備

JDK(Java Development Kit)をインストール
→Java開発キット(JREが含まれている)

環境変数「Path」を設定


コマンドプロンプト

検索窓に「cmd」で起動

「cd フォルダ名」でフォルダ移動(相対or絶対パスで指定)

「dir」で現在のフォルダの中身を表示



プログラムの作成と実行

class クラス名 {
    public static void main(String[] args) {
        実行するプログラム(mainメソッド)
    }
}

「クラス名.java」で保存

「javac クラス名.java」でコンパイル
→「クラス名.class」が生成(バイトコード)

「java クラス名」で実行
→mainメソッドが実行される



コメント

「//コメント」一行コメント

「/* コメント */」複数行コメント

「/** コメント */」文書化(javadoc)コメント



画面出力

改行無し
System.out.print("○○○")

改行する(引数に何も指定しないと改行だけ)
System.out.println("○○○")



文字列

「"」(ダブルクォート)で囲むと文字列
→文字列リテラルと呼ぶ

「+」で文字列を連結

「\n」で改行



記述ルール

読みやすいように「インデント」を入れる

単語の途中でスペースを入れない

文字列の途中で改行を入れない



変数

変数を使うためには「宣言」が必要
→ int x;

変数宣言は2つ以上まとめても可能
→  int x, y;

int型には「整数」が入れられる
→「123」などの数字を「整数リテラル」と呼ぶ

整数÷整数の結果は、小数以下が切り捨てられる

変数宣言と同時に値を代入することを「初期化」という
→ int x = 2;

値の入っていない変数を使うとコンパイルエラー

使用できる文字はAからZ、aからz、0から9、アンダーバー(_)、$
(例) name, old, no32

先頭文字には数字の0から9は使用できない
(例) 12pointなどは×

大文字と小文字は区別される
(例) old と Oldは別の変数

予約語は使用できない
(例) char や classなどの予約語は使用できない

長さの制限は無い



基本型

整数型
→byte, short, int, long(左から順に大きく)

浮動小数点型
→float, double(左から順に大きく)

文字列(基本型ではなくクラス)
→String



定数

finalをつける(PHPのconst)
→final int PI = 3.14;



キーボードからの入力

「import java.util.Scanner;」をファイルの最初に記述

「Scanner stdIn = new Scanner(System.in);」でstdInを生成

「stdIn.nextInt()」で整数を読み込む

「stdIn.next()」「stdIn.nextLine()」で文字列を読み込む




乱数の生成

「import java.util.Random;」をファイルの最初に記述

「Random rand = new Random();」でrandを生成

「rand.next(○○)」で乱数を取得
→「3」を設定すると「0,1,2」を取得できる

※10~99の乱数を取得する場合「rand.next(90)+10」



if文

if (○○==○○) {
    ・・・
} else if (○○==○○) {
    ・・・
} else {
    ・・・
}

ifの処理が1行の場合は{}を省略できる
if (○○○)
    ・・・


switch文

switch (x) {
    case 0:
        ・・・
        break;
    case 1:
    case 2:
        ・・・(a)
        break;
    case 3:
        ・・・(b)
    default:
        ・・・(c)
}

フォールスルー

breakされるまで処理を続ける

※上の例は…

x=1だと(a)が実行される
x=2でも(a)が実行される
x=3だと(b)(c)が実行される



do文

do {
    ・・・
} (x < 10);

【セミコロンを忘れない!】

※この例ではxが10より小さい間ループを続ける
 
(最初からxが10以上でも1回はループする



While文

while (x < 10) {
    ・・・
}

※この例ではxが10より小さい間ループを続ける

(最初からxが10以上ならループしない




インクリメント


前置

x = 3;
y = ++x;

yには「4」が入る
(インクリメントしてから代入)



後置

x = 3;
y = x++;

yには「3」が入る
(代入してからインクリメント)




for文

for (int i = 0; i < 10; i++) {
    ・・・
}

※この例では10回ループが回る



break, continue

for (int i = 1; i <= 10; i++) {
    if (i == 3) {
        continue;
    }
 
    if (i == 5) {
        break;;
    }
}

この例では3回目のループをスキップ、5回目で抜ける



ラベル付ループ

abc:
for (int i = 1; i <= 10; i++) {
    for (int j = 1; j <= 10; j++) {
        if (j == 5) {
            break abc;
        }
    }
 
}

この例では5回目のループで、一番外側のループをまで抜ける



printf

出力したい値をフォーマットできる

「%」を出力したい場合は「%%」とする
→エスケープ処理

System.out.printf("%05f", 123);
→00123

System.out.printf("%6.2f", 12.34567);
→ 12.34



基本型


整数型

char, byte, short, int, long


浮動小数点型

float, double

論理型

boolean




演算と型


型の異なる数値の演算は大きい方の型に変換される

10 / 4 = 1 (int ÷ int = int)

10 / 4.0 = 2.5 (int ÷ double = double)
→int÷doubleなので左辺のintがdoubleに変換される



キャスト

double x = 1.234;
int y = (int)y;

double型の「1.234」がint型に変換され「1」になる



配列


宣言

int[] a;(int a[];でもOKだが昔のやり方であまり使われない)


生成

int[] a = new int[5];
→aは配列本体を参照する変数(参照型)



構成要素のアクセス

int x = a[2];
→配列「a」のインデックス「2」がxに代入される
(インデックスは0から始まる)
※存在しないインデックスを指定すると実行時にエラー



規定値

配列の各要素は各型の規定値で初期化される(intならば0)


要素数の取得

int arrayCount = a.length;
→配列aの要素数を取得



初期化

int[] a = {1, 2, 3, 4, 5};
→宣言と同時だったら初期化できる

int[] a;
a = {1, 2, 3, 4, 5};
→宣言の後に代入はコンパイルエラー

int[] a;
a = new int[]{1, 2, 3, 4, 5};
→これならOK



拡張for文(for-in,for-each)

int a[] = {1, 2, 3, 4};
for (int i : a) {
    System.out.print(i);
}
→配列aの中身が順番にi代入され「1234」と表示される
※phpのforeachと同じ(括弧の中は逆、asではなく:)



短絡評価


int month = 2;
if (month >= 3 && month <= 5) {
    System.out.print("春");
}
※この場合「month >= 3」がfalseでもうifの中を実行しないのが確定、その場合「month <= 5」は評価されない



シャッフルのアルゴリズム

偏らない方法を使うと良い(Fisher-Yatesシャッフル)

Random rand = new Random();
int[] ary = {1,2,3,4,5,6,7,8};
 
for(int i = ary.length; i > 1; --i){
    int index1 = i - 1;
    int index2 = rand.nextInt(i);
 
    //交換
    int temp = ary[index1];
    ary[index1] = ary[index2];
    ary[index2] = temp;
}

文字列の比較はs1.equals(s2)で行う
→(s1 == s2)はアドレスを比較しているだけで間違い



配列のコピー

配列変数を他の変数に代入しても参照先がコピーされるだけ。
→配列の要素1つ1つはコピーされない



空参照とガーベジコレクション

参照型にnullを代入すると、何も参照していない状態になる

String s = "abcd";
s = null; //何も参照していない


どこからも参照されなくなったオブジェクトはガーベジコレクションに回収され消える


finalな変数は参照先を変えることができないが、格要素は変更できる

int [] ary = {1, 2, 3};
ary = null        //エラー
ary = new int[4]; //エラー
ary[1] = 10;      //OK



多次元配列

宣言

//2x4の2次元配列の宣言
int[][] a = new int[2][4];


初期化

//2次元配列の初期化
int[][] b = { {1,2,3}, {4,5,6} };


多次元配列は以下のように動的に要素数を決めることができる

int[][] x = new int[2][];
x[0] = new int[4];
x[1] = new int[7];


※左詰めで最低1個は要素数を指定する必要がある

int[][][] x = new int[][][];   //エラー
int[][][] x = new int[][3][];  //エラー
int[][][] x = new int[4][][2]; //エラー
int[][][] x = new int[4][2][]; //OK


多次元配列も初期化子で初期化できる

int[][] a = {
    {1,2,3},
    {4,5,6},//最後のカンマは無くてもOK
}


バブルソート

int[] ary = {2, 5, 4, 1, 3};
for (int i = 0; i < ary.length - 1; i++) {
    for (int j = i + 1; j < ary.length; j++) {
        if (ary[i] > ary[j]) {
            int temp = ary[i]; //入れ替え
            ary[i] = ary[j];
            ary[j] = temp;
        }
    }
}



メソッド

ひとまとまりの処理はメソッドとしてまとめられる


メソッド宣言

static 戻り値の型※1 メソッド名(仮引数の型 仮引数名※2,…) {
    メソッド本体の処理
}
※1 戻り値が無い場合は「void」
※2 引数は無くても良いし、いくつでも良い
→引数が無い場合は「void method1() {…」のようになる

例)
static int max(int a, int b) {
    if (b > a) {
        return b;
    }
    return a;
}


メソッド呼び出し

//変数xにmaxメソッドの結果が入る
int x = max(1, 3);

→メソッドが呼ばれると、プログラムの流れはメソッド本体に移る



return文

returnでメソッドの戻り値を返し、メソッドの処理をそこで終了する
→戻り値が無い場合は「return;」としてもOK


値渡し

メソッドの引数は値渡しで行われる
→仮引数の値を書き換えても、実引数の引数は変わらない


voidメソッド

戻り値が無いメソッドは戻り値の型の所を「void」と書く
→return文を書かなくても良い、書く場合は「return;」とする


インポートのワイルドカード

java.util.*;
→java.utilパッケージの全てのクラスをインポートする


有効範囲(スコープ)

有効範囲外の変数は使うことができない

class Example {
 
  //フィールド
  static int x;
 
 //メソッド仮引数
  void method1(int y) {

    //フィールドの使い方
    Example.x = 100;
  }
 
  void method2() {
    int z;  // 局所
    if (z == 0) {
      int a; // 局所
    }
  }
}

x:フィールドなのでどこからでもアクセスできる(最強)

y:method1の仮引数なので、method1の中でしかアクセスできない(method2からはアクセスできない)

z:method2の中で宣言された変数なので、method2の中(かつ宣言された後)しかアクセスできない

a:ifブロックの中で宣言された変数なので、ifの中(かつ宣言された後)しかアクセスできない



フィールド

メソッドの外でstaticをつけて宣言する変数でどこからでもアクセスできる
→アクセスするときは「クラス名.フィールド名」とする

class Example {

  //フィールドx
  static int x;
 
  void method() {

    //フィールドに代入
    Example.x = 100;
 
    //表示(100と表示される)
    System.out.print(Example.x);
  }
}


※注意点

フィールドと同じ名前の変数を宣言できてしまう

→その場合は「クラス名.」をつけるとフィールドにアクセスできる

→変数名のみだとローカル変数の方をアクセスしてしまう

※フィールドにアクセスする場合は「クラス名.」をつけた方が間違いがない!



class Example {

  //フィールドx
  static int x;

  public static void main(String[] args) {
 
    //フィールドに代入
    Example.x = 1;
     
    //フィールドを表示(1と表示)
    System.out.print(Example.x);
     
    //単にxとしてもOKだが…(1と表示)
    System.out.print(x);
     
    //フィールドと同じ名前のローカル変数を宣言してもOK
    int x = 2;
     
    //変数名だけだとローカル変数が優先して表示される(2と表示)
    System.out.print(x);
     
    //クラス名.をつければフィールドが表示される(1と表示)
    System.out.print(Example.x);

  }
}


P240~247は授業でやらない



配列を扱うメソッド


メソッドの引数に配列を使うことができる

//引数にint型の配列を使う
static int maxOf(int[] a) {
    ・・・
}



メソッドの戻り値にも配列を使うことができる

//戻り値にint型の配列を使う
static int[] searchOf(int a) {
    ・・・
}



配列の引数

引数に配列を渡すと、配列の参照(アドレス)が渡される
→メソッド内で配列の要素を更新すると、呼び出し元の配列の要素も更新される

class Example {
  static void test1(int[] ary) {
    //引数で渡された配列の要素を書き換える
    ary[0] = 999;
  }
 
  public static void main(String[] args) {
    int[] a = {123, 456, 789};
 
    //123と表示される
    System.out.println(a[0]);
 
    //メソッド内でa[0]が書き換えられる
    test1(a);
 
    //999と表示される
    System.out.println(a[0]);
  }
}



三項演算子(条件演算子)

if-elseの代わりに使うことができる
→以下の処理は同じ結果となる

int x = 10;

//三項演算子
String s = x == 10 ? "YES" : "NO";

//YESと表示される
System.out.print(s);

==========================

int x = 10;
String s = null;

if (x == 10) {
s = "YES";
} else {
s = "NO";
}

//YESと表示される
System.out.print(s);



JavaDocコメント

特別なフォーマットでコメントを書くと、ドキュメントとして出力することができる

/**
 * 受験人数の桁数を取得
 *
 * @param cnt 受験人数
 * @return 受験人数の桁数
 */


1.「/**」で始まり「*/」で終わる
2.「@param 仮引数の変数名」の後にメソッドの引数の説明を記載
3.「@return」の後にメソッドの戻り値の説明を記載
4.「@see」の後に参照先を記載


※文字化けする場合は以下のオプションを追加

-encoding UTF-8
-charset UTF-8




オーバーロード(多重定義)


同じ名前のメソッドを作ることができる
ただし、同じシグネチャのメソッドは作れない


シグネチャ

メソッド名、仮引数の個数、仮引数の型



//このメソッドが既にあったとすると…
static int ave(int x, int y) {
・・・
}

//仮引数の個数が違うのでOK(オーバーロード)
static int ave(int x, int y, int z) {
・・・
}

//仮引数の型が違うのでOK(オーバーロード)
static int ave(String x, String y) {
・・・
}

//返却型が違うだけなので×
static double ave(int x, int y) {
・・・
}

//仮引数の変数名が違うだけなので×
static int ave(int abc, int xyz) {
・・・
}

0 件のコメント:

コメントを投稿