talosのプログラミング教室

Java Silver合格への道

こんにちは。たろすです。

Java Silverでは「こんなのどこで使うんや!」って問題がよく出るのですが、そういうことは覚えにくいのでブログでまとめることにしました。

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

talosta.hatenablog.com

Java Silver合格への道 ~Predicateインタフェース~

こんにちは。たろすです。

今回はPredicateインタフェースについてです。

Function、Consumer、SupplierはJava Silverの試験範囲に含まれていないので扱いません。

関数型インタフェースについて

Predicateインタフェースはあらかじめ用意された関数型インタフェースの一つです。

関数型インタフェースについては以下の記事で説明しています。

https://talosta.hatenablog.com/entry/js-lambdatalosta.hatenablog.com

使い方

boolean test(T t)

test()は引数を受け取ってboolean型を返すメソッドです。

import java.util.function.Predicate;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Predicate<String> p = str -> str.equals("a");
		if (p.test("a")) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

default Predicate and(Predicate other)

二つのPredicate論理積です。

import java.util.function.Predicate;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Predicate<String> p1 = str -> str.contains("a");
		Predicate<String> p2 = str -> str.contains("b");
		Predicate<String> p = p1.and(p2);
		if (p.test("abc")) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

default Predicate negate()

Predicateの論理否定です。

import java.util.function.Predicate;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Predicate<String> p = str -> str.equals("a");
		Predicate<String> _p = p.negate();
		if (_p.test("a")) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

default Predicate or(Predicate other)

二つのPredicateの論理和です。

import java.util.function.Predicate;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Predicate<String> p1 = str -> str.contains("a");
		Predicate<String> p2 = str -> str.contains("b");
		Predicate<String> p = p1.or(p2);
		if (p.test("az")) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

static Predicate isEqual(Object targetRef)

二つの引数が等しいかどうかを判定するメソッドです。

import java.util.function.Predicate;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Predicate<String> p = Predicate.isEqual("a");
		if (p.test("a")) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

おわりに

今回はPredicateインタフェースについて説明しました。

難しいですが量は少ないのでしっかり覚えておきましょう。


Java Silver合格への道 ~関数型インタフェースとラムダ式~

こんにちは。たろすです。

今回は関数型インタフェースとラムダ式についてです。

関数型インタフェースとは

抽象メソッドが1つだけのインタフェースのことを関数型インタフェースといいます。

関数が「入力が1つに決まると出力も1つに決まるもの」であることを考えると覚えやすいと思います。

ラムダ式

Java8から追加された機能です。

ラムダ式を使うことで関数型インタフェースを簡潔に実装することができます。

違いを表すためにまずは従来の方法で実装してみます。

public interface SampleInterface {

	void output(String str);
}
public class SampleClass implements SampleInterface {

	@Override
	public void output(String str) {
		// TODO 自動生成されたメソッド・スタブ

		System.out.println(str);
	}

}
public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		SampleClass sc = new SampleClass();
		sc.output("Hello, world!");
	}

}

こんな簡単な処理を行うだけでも、わざわざクラスを1つ作る必要があります。


続いてラムダ式を使用した実装です。
(インタフェースは同じなので省略します)

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		SampleInterface si = (String str) -> {
			System.out.println(str);
		};
		si.output("Hello, world!");
	}

}

ラムダ式を使うとこのように呼び出し元だけで完結します。
(SampleClassが不要になりました)

しかももっと簡潔に書くこともできます。

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		SampleInterface si = str -> System.out.println(str);
		si.output("Hello, world!");
	}

}


省略できるポイント

1. 引数の型を省略できる
2. 引数が1つで型を省略する場合は()を省略できる
3. 処理が1つの場合は{}を省略できる(※)

※ 処理がreturnの場合は必ずreturnも省略する必要があります。
例:SampleInterface si = str -> {return str}; 
  ⇒ ○ SampleInterface si = str -> str;
    × SampleInterface si = str -> return str;

おわりに

今回は関数型インタフェースとラムダ式について説明しました。

難しいですが少しでも合格の可能性を上げるためにはできるようにしておきましょう。


Java Silver合格への道 ~アンダースコアを用いた数値表記~

こんにちは。たろすです。

今回はアンダースコアを用いた数値表記についてです。

使い方

Java SE 7以降では数値リテラルにアンダースコアを使うことができます。

int x = 123_456;

使える条件

リテラルの先頭と末尾ではないこと
・記号の前後ではないこと

つまり以下のような場合はコンパイルエラーになります。

int y = _123456;
int z = 123456_;
double a = 1._23;
float b = 1.23_f;

おわりに

今回はアンダースコアを用いた数値表記について説明しました。

「,」の代わりに使用すると可読性が上がるかもしれませんね。

Java Silver合格への道 ~可変長引数~

こんにちは。たろすです。

今回は可変長引数についてです。

可変長引数の使い方

public class Sample {

	public void method(int... values) {
		for (int value : values) {
			System.out.println(value);
		}
		System.out.println("------------");
	}
}

メソッドの引数に注目してください。

「int... values」と書かれています。

引数の型の直後に「...」を付けることで可変長引数にすることができます。

可変長引数として渡された引数は配列として扱われます。

このメソッドを実際に使ってみましょう。

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		Sample sample = new Sample();
		sample.method(1, 2, 3);
		sample.method(1, 2, 3, 4, 5);
	}
}
// 出力
1
2
3
------------
1
2
3
4
5
------------

引数に好きなだけ値を渡すことができます。

制約

可変長引数以外の引数も受け取る場合は、可変長引数が最後の引数になるようにしなければなりません。

例えば以下のようなプログラムはコンパイルエラーになります。

public void method(int... values, String str) { }

以下のように直しましょう。

public void method(String str, int... values) { }

可変長引数を二つ以上受け取るのもNGです。

おわりに

今回は可変長引数について説明しました。

配列を渡せば済む話なので、あまり使われているところは見たことありません。

Java Silver合格への道 ~ラベル~

こんにちは。たろすです。

今回はラベルについてです。

ラベルの使い方

まず以下のコードを見てください。

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				System.out.println(i + " " + j);
				if (j == 3) {
					break;
				}
			}
		}
	}
}

二重ループがあり、内側のループの中でjが3と等しければbreakするような構造になっています。

そのためこのプログラムを実行すると、

0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3
4 0
4 1
4 2
4 3

と出力されます。

j(右側の列)が3になったろころで内側のループを抜けていることがわかります。


次に以下のコードを見てください。

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		a: for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				System.out.println(i + " " + j);
				if (j == 3) {
					break a;
				}
			}
		}
	}
}

先程と異なるのは外側のforの左側に「a:」がついていることと、breakの右側に「a」がついていることです。

これをラベルと呼びます。

このプログラムを実行すると以下の出力が得られます。

0 0
0 1
0 2
0 3

jが3と等しくなったところで外側のループを抜けていることがわかります。

これはラベルを付けたことでbreakと外側のforを紐づけたからです。

このようにラベルを使うことでbreakするループを変えたりすることができます。

おわりに

今回はラベルについて説明しました。

goto文同様に可読性が落ちるため現場ではまず見ませんが、Java Silver勉強中は覚えておきましょう。

Java Silver合格への道 ~配列の宣言と初期化~

こんにちは。たろすです。

今回は配列の宣言と初期化についてです。

宣言

OK例

// よく使われる宣言
int[] a;  

// 変数名の後に[]を書くことも可能
int b[];  

// 多次元配列も同様
int[][] c;  
int d[][];

// 分けることもできる
int[] e[];  

NG例

// 宣言時に要素数は指定しない
int a[3];  

初期化

OK例

// 要素を指定するパターン
int[] a = { 1, 2, 3 }; 

// やっていることは上と同じ
int[] b = new int[] { 1, 2, 3 }; 

// 要素数だけを指定するパターン(要素は初期値)
int[] c = new int[3]; 

// 多次元配列の場合は{}の数に注意
int[][] d = { { 1, 2 }, { 3, 4 } }; 

// 要素なしの場合は多次元配列でも{}は1つでOK
int[][] e = {}; 

// N次元目までは要素数を決めておき、N+1次元目以降の要素数は未定にしておくことができる
int[][][]f = new int[3][][];  

NG例

// {}を使う場合は要素数を指定しない
int[] a = new int[3] { 1, 2, 3 }; 

// 宣言と{}を使った初期化は分けられない
int[] b;
b = {1 ,2, 3}; 

// 次元数が一致しない
int[][] c = { 1, 2, 3 }; 

// N次元目の要素数が決まっていないのに、N+1次元目以降の要素数を決めることはできない
int[][][] d = new int [][3][];  

おわりに

今回は配列の宣言と初期化についてOK例とNG例を挙げました。

他の言語などを触っていると間違えやすいので要注意です。