※ 注意:Java 8を想定しています。
型
型に関して
- int, longなどの型を基本型、値型、プリミティブ型という
- StringやIntegerなどの型を参照型、オブジェクト型、ラッパークラスという
- 参照型はさらに、イミュータブル(不変)とミュータブル(可変)に分けられる。
ほとんどがミュータブルで、StringやLocalDate, LocalDateTimeはイミュータブルという認識。
イミュータブルは直接値を変更できず、再代入する必要がある。
型変換に関して
- 右から1つ左に型変換するなら型キャストが必要。例:int a = (型名) b
- 左から右へは暗黙の型変換
- プリミティブ型からラッパークラスへの型変換をオートボクシング、逆をアンボクシングという → リンク
変数と定数
宣言
/* 変数宣言 */
boolean varA; // 宣言のみ
varA = true; // 代入のみ
Class varI // 宣言のみ(参照型)
varI = new Class() // 代入のみ(参照型)
/* 定数宣言 */
static final data_type varJ = valA; // (static + ) final修飾子
配列
固定長配列
/* 宣言 */
data_typeA[] arrayA = new data_typeA[index_max_value];
data_typeB[] arrayB = {valA, valB, valC, valD, valE};
data_typeC[] arrayC = new data_typeC[] {valF, valG, valH};
data_typeD arrayD[]; // 変数名に[]をつけても可
// X arrayD = {valI, valJ, varl}
arrayD = new data_typeD[]{valI, valJ, varl}
data_type[][] arrayE; // 2次元配列 → date_type[] arrayE[]でもよい。
arrayE = new date_typeE[i][]; // 添え字は2つ目省略可。1つ目は不可。
/* arraysクラス */
Arrays.toString(arrayD); // "[valI, valJ, vall]"
Arrays.sort(arrayD); // {vall, valJ, valI}
可変長配列(コレクション)
/* List(インターフェース) */
// X List<data_typeA> listA = new List<>();
List<data_typeA> listA = new ArrayList<>();
List<data_typeB> listB = new LinkedList<>();
List<data_typeC> listC = new CopyOnWriteArrayList<>();
List<data_typeD> listD = Arrays.asList(valA, valB); // 読専
listD.add(valD); // 末尾に追加
listD.add(indexA, valE); // 途中に挿入
listD.set(indexA, valF); // 置換
listD.get(indexA); // 値の取得
listD.indexOf(valF); // 位置の取得
listD.size(); // 要素数の取得
listD.contains(valF); // 存在の確認
listD.remove(valF); // 削除
/* --- 以下Listの実装クラス ------------------------------- */
/* ArrayList .. 検索に強い */
// ArrayListにしか存在しないメソッドを使う場合は下記で宣言(以下同様)
ArrayList<data_typeE> listE = new ArrayList<>();
ArrayList listF = (ArrayList<data_typeE>)listE.clone(); // コピー
/* LinkedList .. 追加/削除に強い */
LinkedList<data_typeG> listG = new LinkedList<>();
listG.push(); // 先頭に追加
listG.pop(); // 先頭から削除
/* CopyOnWriteArrayList .. 同期化不要/マルチスレッドに強い */
CopyOnWriteArrayList<data_typeH> listH = new CopyOnWriteArrayList<>();
連想配列(コレクション)
/* Map(インターフェース) */
// X Map<Integer, data_typeA> mapA = new Map<>();
Map<Integer, data_typeA> mapA = new HashMap<>();
Map<Integer, data_typeB> mapB = new LinkedHashMap<>();
Map<Integer, data_typeC> mapC = new ConcurrentHashMap<>();
Map<Integer, data_typeD> mapD = new TreeMap<>();
mapA.put(keyA, valA); // 末尾に追加
mapA.put(keyA, valB); // 置換
mapA.get(keyA); // 値の取得
mapA.size(); // 要素数の取得
mapA.containsKey(keyA); // キーの検索
mapA.containsValue(valB); // 値の検索
mapA.remove(keyA); // 削除
/* --- 以下Mapの実装クラス ------------------------------- */
/* HashMap ... 検索に強い */
HashMap<Integer, data_typeE> mapE = new HashMap<>();
/* LinkedHashMap .. 挿入した順番を保持 */
LinkedHashMap<Integer, data_typeF> mapF = new LinkedHashMap<>();
/* ConcurrentHashMap .. 同期化不要/マルチスレッドに強い */
ConcurrentHashMap<Integer, data_typeG> mapG = new ConcurrentHashMap<>();
/* TreeMap .. キーの大小を意識した部分集合 */
TreeMap<Integer, data_typeH> mapH = new TreeMap<>();
集合(コレクション)
// X Set<data_typeA> setA = new Set<>();
Set<data_typeA> setA = new HashSet<>();
Set<data_typeB> setB = new LinkedHashSet<>();
Set<data_typeC> setC = new TreeSet<>();
Set<data_typeD> setD = new HashSet<>(ListA); // List->Set
setD.add(valA); // 値の追加/上書き
setD.remove(valB); // 値の削除
setD.size(); // 要素数の取得
setD.contains(valC); // 値の検索
/* --- 以下Setの実装クラス ------------------------------- */
/* HashSet .. 検索に強い */
HashSet<data_typeA> setA = new HashSet<>();
/* LinkedHashSet .. 追加/削除に強い */
LinkedHashSet<data_typeB> setB = new LinkedHashSet<>();
/* TreeSet .. キーの大小を意識した部分集合 */
TreeSet<data_typeC> setC = new TreeSet<>();
ほか
Queueとその実装型 ... FIFO
Queue<data_typeA> queueA = new ArrayBlockingQueue<>(intA);
queueA.offer(valA); // 追加
queueA.peek(); // 出力
queueA.poll(); // 出力/削除
Dequeとその実装型 ... Queueの拡張型。両端から追加削除可能。
// LinkedListはListとDequeの実装型
Deque<data_typeA> dequeA = new LinkedList<>();
dequeA.offerFirst(valA); // 先頭に値の追加
dequeA.offerLast(valB); // 末尾に値の追加
dequeA.peekFirst(valC); // 先頭の値の出力
dequeA.peekLast(valD); // 末尾の値の出力
dequeA.pollFirst(valE); // 先頭の値の出力/削除
dequeA.pollLast(valF); // 末尾の値の出力/削除
分岐
If文
if (conditionA){
statementA // 文、処理
} else if (conditionB) {
statementB // 文、処理
} else if (!conditionC) {
statementC // 文、処理
} else {
statementD // 文、処理
}
/* {}省略 ... ネスト内に文を一行のみ記載可能 */
if (conditionA)
statementA // 文、処理
else
statementB // 文、処理
switch文
switch (varA) {
case valA: // varA = valA の場合
statementA // 文、処理
// break文 ... コードブロックの実行を途中終了
break;
case valB:
case valC: // varA = valB, valC の場合
statementB // 文、処理
break;
case default // varA = valA,valB,valC 以外の場合
statementC // 文、処理
break;
/* caseの順は制限はない。defaultが先頭でも可(非推奨) */
}
反復
For文
/* 指定した回数文繰り返す */
for (data_type varA = valA; varA <= valB; valC++) {
statementA // 文、処理
}
/* for(int a, int b, a < 3, a++, method()){ のように
初期値と更新値は複数定義が可能。更新値はメソッド呼び出しも可能) */
/* 配列コレクションからの繰り返し */
for (data_type varB : collectionA) {
statementB // 文、処理
}
/* forEachとラムダ式の組み合わせ(collectionBの要素を出力する) */
collectionB.forEach(varC -> System.out.println(varC));
While文(Do-While文)
/* 条件式がTrueの間繰り返す */
while (conditionA) {
statementA // 文、処理
}
do {
statementB // 文、処理
} while (conditionB);
/* 条件式がTrueになるまで繰り返す場合 */
while (!conditionC){
statementC // 文、処理
}
do {
statementD // 文、処理
} while (conditionD);
Break文とContinue文
X: // ラベル
while (conditionA) {
switch(varA){
case valA: // statementA,Bを通る
statementA // 文、処理
case valB: // statementBのみ通る
statementB // 文、処理
/* break文 ... コードブロックの実行を途中終了 */
break;
case valC:
break X; // 1行目「X:」のところにジャンプ(Whileを抜ける)
default:
statementC // 文、処理
/* continue文 ... 実行制御を次の反復処理に移す */
continue;
}
}
例外処理 ... エラーをチェックする
/* try ... 対象処理 */
try{
statementA
/* catch ... 例外処理 */
} catch (xxxException e){
e.printStackTrace(); // 例外メッセージ(基本これ)
e.getClass().getName(); // 例外クラス名のみ
e.getMessage(); // 例外詳細メッセージのみ
StackTraceElement[] ste = e.getStackTrace(); // 例外の一覧
/* finally ... try/catch のあと(try/catchにreturnがあっても) 必ず行う処理。 */
} finally{
statementB // 文、処理
}
// try-catch-finallyの順番は変更不可。try-catch, try-finallyなどの省略可。
/* throw句 ... 例外の強制的な生成 */
throw new ExceptionClassA();
/* throws句 ... 呼び出し元にエラーを渡す */
public class Main throws Exception { // mainにつけると例外がどっかいく
例外の種類
クラス | 概要 | 発生タイミング |
---|---|---|
Error | 実行環境のトラブルなど、プログラムからは対処しようのないエラー | 実行時(非検査項目) |
Exception - RuntimeException | プログラムを正しく書けば防げるException | 実行時(非検査項目) |
Exception - 上記以外 | プログラムを正しく書いても防げないException。throws必須 | コンパイル時(検査項目) |
クラス
クラスの基本
package scope1.packageA; // パッケージ宣言
import scopeB.libC; // 別パッケージBのlibCをインポート
import static scopeC.libD.methodA; // 別パッケージCのlibDのmethodAメソッドをstaticインポート
public class ClassA{
/* 始めに呼ばれるメソッド */
// mainの引数パターンは他に(String... args), (String args[])
public static void main(String[] args){
ClassB instanceA = new ClassB("naiyo");
System.out.println(instanceA.getMethodA());
}
}
private class ClassB{
private data_type _fieldA;
/* staticイニシャライザ ... staticアクセス、インスタンス生成など、
初めてクラスがロードされた時に最初に実行 */
static {
// 初期化処理など。
}
/* 初期化ブロック ... 毎回インスタンスが生成された時に最初に実行 */
{
// 初期化処理など
}
/* コンストラクタ ... 毎回インスタンスが生成された時に最初に実行 */
Class2(){
this._fieldA = "";
}
/* 順番は staticイニシャライザ -> 初期化ブロック -> コンストラクタ */
/* セッター */
data_type setMethodA(data_type varB){
this._fieldA = varB; // 引数とフィールド名は同じ
}
/* ゲッター */
data_type getMethodA(){
return this._fieldA;
}
}
修飾子
/* アクセス修飾子 */
private class1{} // 同クラスからのみアクセスできる
protected class class1{} // 同クラスとサブクラスからのみ
class class1{} // 同パッケージからのみ
public class class1{} // 全てのクラスから
/* 他修飾子 */
abstract // 抽象クラス、抽象メソッド
static // クラス名.メンバで呼び出し可, static以外のメンバにアクセス不可
final // 上書きされない(定数)
synchronized // 複数プロセス時排他制御を行う
native // ネイティブクラス、ネイティブメソッド
strictfp // IEEE754に則って浮動小数点数を演算処理する
transient // シリアライズの対象から除外
volatile // フィールド値のキャッシュを抑制する
const // 多言語の定数修飾子、Javaでは使用せず
/* アノテーション */
@Deprecated // 非推奨であることを明示
@Override // 上書きしていることを明示
@SuppressWarning // 警告表示を抑制
/* 順番 */
@Annotation
public protected private
abstract static final synchronized native strictfp
継承(多態性)
継承の基本
/* 親クラス */
protected class ClassA{
protected data_type fieldA;
protected Class1(data_type varA){ // 親クラスのコンストラクタ
this.fieldA = varA;
}
protected void methodA(data_type varB){ // 親クラスのメソッド
statementA
}
}
/* 子クラス */
public class ClassB extends ClassA{
public ClassB(data_type varC){ // 子クラスのコンストラクタ
super(varC); // 親クラスのコンストラクタを呼び出す
}
@Override // オーバーライド修飾子(前述)
public void methodA(data_type var2){
statementB // 文、処理
}
}
抽象クラス ... 雛型、共通の処理を実装したい
/* 抽象クラス */
protected abstract class ClassA{
protected data_type fieldA;
public Class1(data_type varA){
this.fieldA = varA
}
// オーバーライドされる前提のメソッド(抽象メソッド)
public abstract void methodA(data_type varB);
}
/* 子クラス */
protected abstract class ClassB{
@Override
public abstract void methodA(data_type varB){
statementA // 文、処理
}
}
インターフェース ... 抽象メソッドと定数しか定義ができない(原則)
/* インターフェース */
public interface InterfaceA{
/* 基本的に以下のように、型の羅列を行う */
data_type CONST_A = "CONST_A"; // public static finalは省略可
data_type methodA(data_type varA);
/* ---- 以下Java8から追加。個人的に非推奨(複雑なため) ---- */
// defaultメソッド ... 抽象クラスの通常メソッドのようなもの
default void methodB(data_type varB){
statementA // 文、処理
}
// staticメソッド ... インスタンスなしで呼び出し可
public static methodC(data_type varC){
statementB // 文、処理
}
}
/* 子クラス */
public class ClassB extends InterfaceA{
public static void main(String[] args){
@Override
public static methodB(data_type varB){
// X ClassB.methodC
// X @Override methodC
InterfaceA.methodC(Interface1.CONST_A);
}
}
色々なクラス
ジェネリックスクラス(テンプレート)
public class GenericClassA<TYPE>{
private TYPE _fieldA;
GenericClassA(TYPE varA){
this._fieldA = varA;
}
TYPE setMethodA(TYPE varB){
this._fieldA = varB;
}
TYPE getMethodA(){
return this._fieldA;
}
}
/* ジェネリックメソッド */
public class ClassA{
public static <TYPE> ArrayList<TYPE> GenericMethodA(TYPE val1){
}
}
インナークラス
public class ClassA{
/* staticメンバークラス ... */
static class MemberClassA{}
/* 非staticメンバークラス ... */
class MemberClassB{}
public static void main(String[] args) {
/* ローカルクラス ... */
class LocalClassC{
public void localMethod(){}
}
LocalClassC localClassC = new LocalClassC();
localClassC.localMethod();
/* 匿名クラス ... 定義とインスタンス化を同時にできる */
// ArrayList型を継承した匿名クラス
List<data_typeC> list = new ArrayList<data_typeC>() {
public data_typeC method3() {
statements // 文、処理
}
};
}
}
public class ClassB{
public static void main(String[] args){
// staticメンバークラス呼び出し
ClassA.MemberClassA cAcA = new ClassA.MemberClassA();
// 非staticメンバークラス呼び出し
ClassA cA = new ClassA();
ClassA.MemberClassB cAcB = cA.new MemberClassB();
}
}
モジュール(Java9)
module-info.java
module moduleA{ // module-info.javaというファイルに記載。
export moduleA.lib; // 本モジュール内のライブラリを公開する
requires moduleB; // 本モジュールが必要とするモジュールを記載する
}
参考:モジュールシステムを学ぶ / Java Modules
enum(列挙型)
public enum EnumA{
/* 基本 */
elmA, elmB;
/* 応用 - メンバ、変数、メソッドの追加 */
elmC(0), elmD(1);
private final int fieldA;
private setElmA(int varA){
this.fieldA = varA;
}
public int getVal(){
return fieldA;
}
public void outVal(){ // values() .. 全enum要素のリスト
for (Enum2 enums : values()) {
System.out.println(enums.getVal()); // 0, 1
}
}
}
ラムダ式(Java8)
書き方
/* (args) -> { statements // 文、処理 } */
// 一つの場合は args -> statements
Collections.sort(listA, (a,b) -> {return b - a;});
メソッド参照
/* スタティックメソッド(class::method)*/
// list.forEach(i -> String.toString(i)));
list.forEach(String::toString);
/* メンバーメソッド(this::method) */
// list.forEach(i -> this.toString(i)));
list.forEach(this::toString);
/* ジェネリックメソッド(class::<type> method) */
// list.forEach(i -> ClassA<typeA> methodA(i);));
list.forEach(ClassA::<typeA> methodA);
/* インスタンスメソッド(object::method) */
// list.forEach(i -> System.out.print(i));
list.forEach(System.out::print);
/* コンストラクタ(class::new) */
ClassA instanceA = classA::new;
関数型インターフェース
... 抽象メソッド1つしか定義されていない等、条件を満たすとラムダ式やメソッド参照の代入先になれる
@FunctionalInterface
public interface FuncInterfaceA {
public data_typeA method(data_typeA varA);
}
/* メジャーな標準の関数型インターフェース */
// Function.apply() 値を変換する
Function<String, Integer> func = x -> x.length();
System.out.println(func.apply("mojisu")); // 6
// Predicate.test() 判定を行う
Predicate<Integer> condA = i -> i != 0 ;
Predicate<Integer> condB = i -> i % 2 == 0 ;
condA.test(2); // true
condA.negate().test(1); // false (negate..否定)
condA.or(condB).test(1); // true (or判定)
condA.and(condB).test(1); // false (and判定)
// Supplier.get() 引数なしで値を返す
Supplier nowTime = () -> LocalDateTime.now();
System.out.println(nowTime.get()); // 2020-01-22 12:34:56
// Consumer.accept() 引数を元に処理
Consumer<String> printA = str -> {
System.out.println("printA: " + str);
}
Consumer<String> printA = str -> {
System.out.println("printB: " + str);
}
Consumer<String> printAll = printA.andThen(printB); // 結合する
printAll.accept("" + System.currentTimeMillis());
参考:Java8のラムダ式を理解する / Java関数型インターフェース
ストリームAPI(Java8)
// Streamを生成
Stream<data_typeA> streamA = listA.stream(); // stream()をつける
IntStream intStreamA = IntStream.range(1,5); // 数値からStreamを作成
// 中間操作
streamA.filter(p -> p.length() > 5); // 絞り込む
streamA.map(p -> "[" + p + "]"); // 置き換える
// 終端操作
List<data_typeB> listB = streamA.collect(Collectors.toList()); // 変換
// 出力
listB.forEach(System.out::println);
/* ワンライナー */
listA.stream()
.filter(p -> p.length() > 5)
.map(p -> "[" + p + "]")
.collect(Collectors.toList())
.forEach(System.out::println);
中間操作メソッド
メソッド | 処理内容 | 例 |
---|---|---|
map | 要素を別の値に置き換える | .map(s-> s.getMethod()) |
flatmap | 要素のStreamを結合する | .flatmap(s -> s2.stream()) |
filter | 合致した要素を絞り込む | .filter(s -> s.equals(1) |
limit | 指定した件数に絞り込む | .limit(2) |
distinct | ユニークな要素のみに絞り込む | .distinct() |
sorted | 要素を並び替える | .sorted((s1,s2) -> s2-s1) |
range | 末尾の値を含まず数列を作る | IntStream.range(1,5) |
rangeClosed | 末尾の値を含み数列を作る | IntStream.rangeClosed(1,5) |
終端操作メソッド
メソッド | 処理内容 | 例 |
---|---|---|
forEach | 繰り返し処理をする | .forEach(System.out::println); |
collect | 結果を作成する | .collect(Collectors.toList()); |
toArray | 配列に変換する | .toArray(String[]::new); |
reduce | 値を集約する | .reduce((val1,val2) -> val1.add(val2)); |
toList | Listにして返す | .collect(Collectors.toList()); |
toSet | Setにして返す | .collect(Collectors.toSet()); |
joining | 区切り文字で結合する | .collect(Collectors.joining(",")); |
groupingBy | 要素をグループ分けする | .collect(Collectors.groupingBy(s -> s.length())); |
※ あくまでメモなので、間違いがあるかもしれないですがご了承ください |