はじめに
今日からついにジェネリクスに突入しました!
今日読んだところ
101 ページ〜 125 ページ
関数オブジェクト
インスタンスメソッドを一つだけ持っているクラスのオブジェクト。
C++ の関数ポインタのような、 JavaScript のクロージャのような使われ方をする。
関数オブジェクトのインスタンスは複数いらない
以下のように、シングルトンにしたり、 public static final なフィールドに入れられたりする。
import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Main { public static void main(final String[] args) { List<String> list = Arrays.asList("aaaa", "baaabaaaaaaa", "cacaca"); Collections.sort(list, CountAComparator.INSTANCE); System.out.println(list); } } enum CountAComparator implements Comparator<CharSequence> { INSTANCE; @Override public int compare(CharSequence cs1, CharSequence cs2) { return countA(cs1) - countA(cs2); } private int countA(CharSequence cs) { int count = 0; for (int i = 0; i < cs.length(); i++) { char c = cs.charAt(i); if (c == 'a' || c == 'A') { count++; } } return count; } }
static メンバクラスに戦略を保持する
そういうやりかたもする
class Klass { pravate static class Comparator extends Comparator<String> { // snip } // snip }
無名クラスとして使われたりもする
import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Main { public static void main(final String[] args) { List<Integer> list = Arrays.asList(1, 10, 100); final int base = 30; // 30 から近い順にソート Collections.sort(list, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Math.abs(base - o1.intValue()) - Math.abs(base - o2.intValue()); } }); System.out.println(list); } }
ネストしたクラスの 3 種類
それぞれの用途まとめ
- static メンバクラス
- クラスの構成要素を作る
- 非 static なメンバクラス
- クラスのアダプタを定義する(イテレータとかね
- 無名クラス
- 関数オブジェクトやプロセスオブジェクト
- ローカルクラス
- あまり使わない
エンクロージングインスタンス
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class Main { public static void main(final String[] args) { JFrame f = new JFrame(); JButton b = new JButton("click"); f.getContentPane().add(b); f.pack(); f.setVisible(true); b.addActionListener(new Hoge().createListener()); } } class Hoge { public ActionListener createListener() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(data); // この場所で、 } }; } // ここの this.data にアクセスできている!! // ここの this をエンクロージングインスタンスという private final String data = "hoge"; }
for-each ループすごい!
for (String s : list) { } みたいな書き方できるんだ!すげー!
原型を使う 2 パターン
- クラスリテラル
- List.class, Set.class
- instanceof
- obj instanceof List, obj instanceof Set
非境界型ワイルドカード
- null 以外なにも入れられない
- オブジェクトとしてしか受け取れない
import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { foo(Arrays.asList("")); } public static void foo(List<?> e) { Object o = e.get(0); e.add(o); // コンパイルエラー } }
境界型ワイルドカード
import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { foo(Arrays.asList("")); } public static void foo(List<? extends CharSequence> e) { // CharSequence で受け取れる CharSequence o = e.get(0); } }
import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { foo(Arrays.asList("")); } public static void foo(List<? super String> e) { // String で受け取れる e.add(""); } }
無検査警告を取り除く
@SuppressWarnings("unchecked")
まとめ
明日は、予定があるのでまとめてる時間ないかもなー><