SlideShare a Scribd company logo
1 of 124
Download to read offline
Java 8 勉強会
第一回
ラムダ式 (1)
2015/3/2
開発部 3G 野口光太郎
ついに
Java 8
が使える
Java 8 導入予定
• Thunderbus
• 1.0 で導入済(8u31)
• PIMSYNC
• 2.2 で導入予定
• DataSpider Servista
• 4.0 で導入予定
Java 8 の新機能
• ラムダ式
• Stream API
• Date and Time API
• JavaFX 8
• etc…
Java 8 の新機能
• ラムダ式
• Stream API
• Date and Time API
• JavaFX 8
• etc…
ついに
ラムダ式
が使える
Java 8 勉強会
第一回
ラムダ式 (1)
2015/3/2
開発部 3G 野口光太郎
アジェンダ
1. ラムダ式は何が違うのか
2. ラムダ式を書く
3. forEach によるイテレーション
1.
ラムダ式は
何が
違うのか
ラムダ式とは
• 匿名関数の簡略な記法
• Java 8(2014/3)で導入
• 取り立てて新しい概念ではない
• C++11(2011 年)
• C# 3.0(2008 年)
• Lisp(ざっと 50 年くらい前)
ラムダ式とは
• 匿名関数の簡略な記法
• Java 8(2014/3)で導入
• 取り立てて新しい概念ではない
• C++11(2011 年)
• C# 3.0(2008 年)
• Lisp(ざっと 50 年くらい前)
匿名関数の
簡略な記法
……?
匿名関数とは
• 匿名の関数
• 要するにこれのこと
List<Integer> numbers = Arrays.asList(1, 1, 2, 3, 5);
Collections.sort(numbers, new Comparator<Integer>() {
@Override
public int compare(Integer i1, Integer i2) {
return i2 - i1;
}
});
匿名関数の簡略な記法
• こう書ける
List numbers = Arrays.asList(1, 1, 2, 3, 5);
Collections.sort(numbers, (i1, i2) -> i2 - i1);
で?
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
new Assertion() {
@Override
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
}
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
new Assertion() {
@Override
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column)
throws Exception {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
}
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
new Assertion() {
@Override
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
}
ノイズ
・new
・Assertion()
・@Override
・public
・void
・call
テストの内容にとっては全部どうでもいい
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
new Assertion() {
@Override
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column)
throws Exception {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
}
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
(expectedSheet, actualSheet, row, column) -> {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
} • こう書ける
Excel アダプタのテスト
コードの例(Before)
• こういうのも
private interface Assertion {
public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception;
}
private void assertDataAndFormat(String expectedExcelFileName, String sheetName,
int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception {
assertWithExpectedExcelFile(
expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex,
(expectedSheet, actualSheet, row, column) -> {
Cell expetedCell = expectedSheet.getCell(column, row);
Cell actualCell = actualSheet.getCell(column, row);
assertEquals(expetedCell.getContents(), actualCell.getContents());
assertEquals(expetedCell.getType().toString(), actualCell.getType().toString());
assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(),
actualCell.getCellFormat().getFormat().getFormatString());
AssertUtil.assertCellFormatByJExcelApi(
expetedCell.getCellFormat(), actualCell.getCellFormat());
}
}
);
}
Excel アダプタのテスト
コードの例(After)
(匿名関数)
• こう書ける
• メソッドに関数を直接渡せる
(注意)
実際に過去に書いたコードの中からノイズが減って
嬉しい例としてたまたまこれを思い出したので挙げ
ましたが、関数型のスタイルという観点では、そも
そもあまり長いラムダ式は推奨されない、という考
え方もあるようです。
あとそもそもアサーションの仕方がダサいとかは今
はツッコまない方向で……。
xxx アダプタのテスト
コードの例(Before)
• こういうのも
@Test public void ソート_標準カラム_文書管理番号_昇順()
throws Exception {
ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0,
new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2){
return o1.getDocNum() - o2.getDocNum();
}
});
}
xxx アダプタのテスト
コードの例(Before)
• こういうのも
@Test public void ソート_標準カラム_文書管理番号_昇順() throws Exception {
ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
return o1.getDocNum() - o2.getDocNum();
}
});
}
@Test public void ソート_標準カラム_文書管理番号_降順() throws Exception {
ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
return o2.getDocNum() - o1.getDocNum();
}
});
}
1
@Test public void ソート_標準カラム_文書名_昇順() throws Exception {
ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getDocName();
String v2 = o2.getDocName();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_文書名_降順() throws Exception {
ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getDocName();
String v2 = o2.getDocName();
return compareNull(v2, v1);
}
});
}
@Test public void ソート_標準カラム_コンピューター名_昇順() throws Exception {
ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getComputerName();
String v2 = o2.getComputerName();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_コンピューター名_降順() throws Exception {
ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getComputerName();
String v2 = o2.getComputerName();
return compareNull(v2, v1);
}
});
}
2
@Test public void ソート_標準カラム_ユーザー名_昇順() throws Exception {
ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getUserName();
String v2 = o2.getUserName();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_ユーザー名_降順() throws Exception {
ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getUserName();
String v2 = o2.getUserName();
return compareNull(v2, v1);
}
});
}
@Test public void ソート_標準カラム_印刷プリンター名_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getPrinterName();
String v2 = o2.getPrinterName();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_印刷プリンター名_降順() throws Exception {
ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getPrinterName();
String v2 = o2.getPrinterName();
return compareNull(v2, v1);
}
});
}
3
@Test public void ソート_標準カラム_印刷プリンターグループ名_昇順() throws Exception {
ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getPrinterGroupName();
String v2 = o2.getPrinterGroupName();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_印刷プリンターグループ名_降順() throws Exception {
ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
String v1 = o1.getPrinterGroupName();
String v2 = o2.getPrinterGroupName();
return compareNull(v2, v1);
}
});
}
@Test public void ソート_標準カラム_スプール開始時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getSpoolStartTime();
Date v2 = o2.getSpoolStartTime();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_スプール開始時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getSpoolStartTime();
Date v2 = o2.getSpoolStartTime();
return compareNull(v2, v1);
}
});
}
4
@Test public void ソート_標準カラム_スプール終了時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getSpoolEndTime();
Date v2 = o2.getSpoolEndTime();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_スプール終了時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getSpoolEndTime();
Date v2 = o2.getSpoolEndTime();
return compareNull(v2, v1);
}
});
}
@Test public void ソート_標準カラム_印刷開始時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getPrintStartTime();
Date v2 = o2.getPrintStartTime();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_印刷開始時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getPrintStartTime();
Date v2 = o2.getPrintStartTime();
return compareNull(v2, v1);
}
});
}
5
@Test public void ソート_標準カラム_印刷終了時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getPrintEndTime();
Date v2 = o2.getPrintEndTime();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_印刷終了時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getPrintEndTime();
Date v2 = o2.getPrintEndTime();
return compareNull(v2, v1);
}
});
}
@Test public void ソート_標準カラム_最終更新時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 0, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getUpdateTime();
Date v2 = o2.getUpdateTime();
return compareNull(v1, v2);
}
});
}
@Test public void ソート_標準カラム_最終更新時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 1, new Comparator() {
@Override
public int compare(XXXDocument o1, XXXDocument o2) {
Date v1 = o1.getUpdateTime();
Date v2 = o2.getUpdateTime();
return compareNull(v2, v1);
}
});
}
6
22 テストケース
6 ページ
247 行
• こう書ける
@Test public void ソート_標準カラム_文書管理番号_昇順() throws Exception {
ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0,
(o1, o2) -> o1.getDocNum() - o2.getDocNum());
}
@Test public void ソート_標準カラム_文書管理番号_降順() throws Exception {
ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 1,
(o1, o2) -> o2.getDocNum() - o1.getDocNum());
}
@Test public void ソート_標準カラム_文書名_昇順() throws Exception {
ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 0,
(o1, o2) -> compareNull(o1.getDocName(), o2.getDocName());
}
@Test public void ソート_標準カラム_文書名_降順() throws Exception {
ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 1,
(o1, o2) -> compareNull(o2.getDocName(), o1.getDocName());
}
@Test public void ソート_標準カラム_コンピューター名_昇順() throws Exception {
ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 0,
(o1, o2) -> compareNull(o1.getComputerName(), o2.getComputerName());
}
xxx アダプタのテスト
コードの例(After)
1
@Test public void ソート_標準カラム_コンピューター名_降順() throws Exception {
ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 1,
(o1, o2) -> compareNull(o2.getComputerName(), o1.getComputerName());
}
@Test public void ソート_標準カラム_ユーザー名_昇順() throws Exception {
ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 0,
(o1, o2) -> compareNull(o1.getUserName(), o2.getUserName());
}
@Test public void ソート_標準カラム_ユーザー名_降順() throws Exception {
ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 1,
(o1, o2) -> compareNull(o2.getUserName(), o1.getUserName());
}
@Test public void ソート_標準カラム_印刷プリンター名_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 0,
(o1, o2) -> compareNull(o1.getPrinterName(), o2.getPrinterName());
}
@Test public void ソート_標準カラム_印刷プリンター名_降順() throws Exception {
ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 1,
(o1, o2) -> compareNull(o2.getPrinterName(), o1.getPrinterName());
}
@Test public void ソート_標準カラム_印刷プリンターグループ名_昇順() throws Exception {
ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 0,
(o1, o2) -> compareNull(o1.getPrinterGroupName(), o2.getPrinterGroupName());
}
@Test public void ソート_標準カラム_印刷プリンターグループ名_降順() throws Exception {
ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 1,
(o1, o2) -> compareNull(o2.getPrinterGroupName(), o1.getPrinterGroupName());
}
@Test public void ソート_標準カラム_スプール開始時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 0,
(o1, o2) -> compareNull(o1.getSpoolStartTime(), o2.getSpoolStartTime());
}
@Test public void ソート_標準カラム_スプール開始時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 1,
(o1, o2) -> compareNull(o2.getSpoolStartTime(), o1.getSpoolStartTime());
}
@Test public void ソート_標準カラム_スプール終了時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 0,
(o1, o2) -> compareNull(o1.getSpoolEndTime(), o2.getSpoolEndTime());
}
2
@Test public void ソート_標準カラム_スプール終了時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 1,
(o1, o2) -> compareNull(o2.getSpoolEndTime(), o1.getSpoolEndTime());
}
@Test public void ソート_標準カラム_印刷開始時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 0,
(o1, o2) -> compareNull(o1.getPrintStartTime(), o2.getPrintStartTime());
}
@Test public void ソート_標準カラム_印刷開始時刻_降順() throws Exception {
(o1, o2) -> compareNull(o2.getPrintStartTime(), o1.getPrintStartTime());
}
@Test public void ソート_標準カラム_印刷終了時刻_昇順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 0,
(o1, o2) -> compareNull(o1.getPrintEndTime(), o2.getPrintEndTime());
}
@Test public void ソート_標準カラム_印刷終了時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 1,
(o1, o2) -> compareNull(o2.getPrintEndTime(), o1.getPrintEndTime());
}
@Test public void ソート_標準カラム_最終更新時刻_昇順() throws Exception {
(o1, o2) -> compareNull(o1.getUpdateTime(), o2.getUpdateTime());
}
@Test public void ソート_標準カラム_最終更新時刻_降順() throws Exception {
ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 1,
(o1, o2) -> compareNull(o2.getUpdateTime(), o1.getUpdateTime());
}
3
22 テストケース
3 ページ
107 行
テストケース数 :
22 → 22 (100%)
ページ数 :
6 → 3 (50%)
行数 :
247→107 (43%)
嬉しい
• ノイズの減少
• 本質的なコードだけが残る
• 一覧性の向上
• たとえばテストがスペックに近
づく
• 気がする
Q:
ラムダ式は
何が
違うのか
A:
匿名関数が
簡略に書けて
嬉しい
それだけ?
そうだけど、
(全然むずかしくない)
そうではない。
(文字数が減るとか、
それだけではない)
開かれる
関数型スタイルへの道
• 私たちが愛する
• 不変性
• 実装の隠蔽
• ドキュメントとしてのコード
• 遅延評価
• 並列化
がもたらされる
ことを他の人が
次回以降に説明
してくれます
2.
ラムダ式を
書く
2. ラムダ式を書く
• 何をラムダ式で書けるのか
• どのようにラムダ式を書けるのか
• いつラムダ式を書くべきか
• ラムダ式さえ書かなくてもよいと
きもある
2. ラムダ式を書く
• 何をラムダ式で書けるのか
• どのようにラムダ式を書けるのか
• いつラムダ式を書くべきか
• ラムダ式さえ書かなくてもよいと
きもある
Q :
何をラムダ式で
書けるのか
A :
関数型インタ
フェースをラム
ダ式で置き換え
ることができる
関数型インタフェース
• 実装が必要なメソッドを一つだけ
持つインタフェース
• 実装が必要なメソッド?
→ 未実装の abstract メソッド
• 唯一の abstract メソッド以外に、
static メソッドや default メソッ
ドが定義されている場合もある
関数型インタフェースの例
• ~ JDK 7
• Runnable
• Callable
• Comparator
• JDK 8 ~
• Predicate
• Consumer
• Supplier
関数型インタフェースの例
• ~ JDK 7
• Runnable
• Callable
• Comparator
• JDK 8 ~
• Predicate
• Consumer
• Supplier
JDK 7 までの Comparator
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
JDK 8 の Comparator
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
... (6 default methods)
public static <T extends Comparable<? super T>> Comparator<T>
reverseOrder() {
return Collections.reverseOrder();
}
... (8 static methods)
}
@FunctionalInterface
• 関数型インタフェースにつけるこ
とができるアノテーション
• つけなくてもよい
• つけるとコンパイラが関数型イ
ンタフェースかどうかチェック
してくれる
• 人間の目にもやさしい
デフォルトメソッド
• インタフェースに実装を定義でき
る記法
• default キーワードを記述
• 後方互換性を保ちながらインタ
フェースを拡張するために導入
された
• 詳細は次回……。
2. ラムダ式を書く
• 何をラムダ式で書けるのか
• どのようにラムダ式を書けるのか
• いつラムダ式を書くべきか
• ラムダ式さえ書かなくてもよいと
きもある
Q :
どのように
ラムダ式を
書けるのか
A :
次のように
ラムダ式の記法
• ( 実装するメソッドの引数 ) -> { 処理 }
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(Integer o1, Integer o2) -> { return o1 – o2 }
ラムダ式の記法
• ( 実装するメソッドの引数 ) -> { 処理 }
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(Integer o1, Integer o2) -> { return o1 – o2 }
ラムダ式の記法
• ( 実装するメソッドの引数 ) -> { 処理 }
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(Integer o1, Integer o2) -> { return o1 – o2; }
ここから色々と
省略できる
ラムダ式の記法 (省略前)
• ( 実装するメソッドの引数 ) -> { 処理 }
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(Integer o1, Integer o2) -> { return o1 – o2; }
ラムダ式の記法 (省略 1)
• 型推論
• 例 : Comparator の場合
int compare(Integer o1, Integer o2)
に対して
(Integer o1, Integer o2) -> { return o1 – o2; }
ラムダ式の記法 (省略 1)
• 型推論
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(o1, o2) -> { return o1 – o2; }
ラムダ式の記法 (省略 2)
• 波括弧(「{}」)と return の省略
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(o1, o2) -> { return o1 – o2; }
ラムダ式の記法 (省略 2)
• 波括弧(「{}」)と return の省略
• 例 : Comparator<Integer> の場合
int compare(Integer o1, Integer o2)
に対して
(o1, o2) -> o1 – o2
ラムダ式の記法 (省略 3)
• 丸括弧(「()」)の省略
• 丸括弧が省略できるのは、メソッドの引数
が 1 つだけの場合
ラムダ式の記法 (省略 3)
• 丸括弧(「()」)の省略前
• 例 : Predicate<Integer> の場合
boolean test(Integer t)
に対して
(Integer t) -> { return (t > 100); }
ラムダ式の記法 (省略 3)
• 丸括弧(「()」)の省略後
• 例 : Predicate<Integer> の場合
boolean test(Integer t)
に対して
(Integer t) -> { return (t > 100); }
ラムダ式の記法 (省略 3)
• 丸括弧(「()」)の省略後
• 例 : Predicate<Integer> の場合
boolean test(Integer t)
に対して
t -> { return (t > 100); }
ラムダ式の記法 (省略 3)
• さらに省略すると
• 例 : Predicate<Integer> の場合
boolean test(Integer t)
に対して
t -> { return (t > 100); }
ラムダ式の記法 (省略 3)
• さらに省略すると
• 例 : Predicate<Integer> の場合
boolean test(Integer t)
に対して
t -> t > 100
ラムダ式の記法 (引数なし)
• メソッドに引数がない場合
丸括弧のみ記述する
ラムダ式の記法 (引数なし)
• メソッドに引数がない場合
丸括弧のみ記述する
• 例 : Callable<Integer> の場合
Integer call()
に対して
() -> { return 100; }
ラムダ式の記法 (引数なし)
• メソッドに引数がない場合
丸括弧のみ記述する
• 例 : Callable<Integer> の場合
Integer call()
に対して
() -> { return 100; }
ラムダ式の記法
(実質的に final)
• 実質的に final
• 匿名クラスでは、メソッド内で参照
するローカル変数には final キー
ワードが必要
• ラムダ式では、その変数について
final と同等に扱っていれば、final
キーワードは不要
ラムダ式の記法
(this が表すもの)
• http://www.atmarkit.co.jp/ait/
articles/1403/17/news105_2.h
tml
• (手抜きでスミマセン……)
2. ラムダ式を書く
• 何をラムダ式で書けるのか
• どのようにラムダ式を書けるのか
• いつラムダ式を書くべきか
• ラムダ式さえ書かなくてもよいと
きもある
Q :
いつラムダ式を
書くべきか
A :
書けるところ
ならどこでも
書けるところなら
どこでもラムダ式を書く
• ラムダ式は関数型インタフェースの略
記法にすぎない
• むずかしくない
• こわくない
• ラムダ式はノイズを減らして本質を残
す
• 簡潔で読みやすいコードをつくる
と思っていますが、
プロダクション
コードで色々と書
くにつれて合わな
い場面が出てくる
かもしれません
たとえば、ラムダ式の
意味をよく知っている
(今のみなさん)にも
かかわらず、なぜか読
みづらい、という場面
があるかも……?
そういうときは
コードレビュー等
を通して適宜共有
していきましょう
2. ラムダ式を書く
• 何をラムダ式で書けるのか
• どのようにラムダ式を書けるのか
• いつラムダ式を書くべきか
• ラムダ式さえ書かなくてもよいと
きもある
ラムダ式さえ書かなくて
もよいときもある
• メソッド参照
• ざっくり言うとこう書ける仕組み
• Before :
name -> System.out.println(name)
• After :
System.out.println
• のちほどもうちょっと説明します
3.
forEach による
イテレーション
forEach による
イテレーション
• ラムダ式の活用例
• イテレーションが高級になっていく歴
史
• for (int i = 0; i < list.size(); i++)
• for (String s : list)
• list.forEach()
forEach による
イテレーション
• ラムダ式の活用例
• イテレーションが高級になっていく歴
史の第三段階
• for (int i = 0; i < list.size(); i++)
• for (String s : list)
• list.forEach()
原始 for 文
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
for (int i = 0; i < members.size(); i++) {
System.out.println(members.get(i));
}
原始 for 文
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
for (int i = 0; i < members.size(); i++) {
System.out.println(members.get(i));
}
• ノイズが多い
• OBOE や変数の取り違えが
起こりかねない
拡張 for 文(Java 5~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
for (String member : members) {
System.out.println(member);
}
拡張 for 文(Java 5~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
for (String member : members) {
System.out.println(member);
}
• もう OBOE は起こらない
• が、まだ冗長だ……。
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
Members.forEach(new Consumer<String>() {
public void accept(final String name) {
System.out.println(name);
}
});
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(new Consumer<String>() {
public void accept(final String name) {
System.out.println(name);
}
});
• ウッけっこうノイズが多いような
……
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(new Consumer<String>() {
public void accept(final String name) {
System.out.println(name);
}
});
• そんなときのためのラムダ式
• 1
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(
(final String name) ->
System.out.println(name));
• そんなときのためのラムダ式
• 1
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(
(final String name) ->
System.out.println(name));
• そんなときのためのラムダ式
• 2
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(
name -> System.out.println(name));
• そんなときのためのラムダ式
• 2
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(
name -> System.out.println(name));
• そんなときのためのラムダ式
• さえいらない(メソッド参照)
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(System.out.println);
• そんなときのためのラムダ式
• さえいらない(メソッド参照)
forEach(Java 8~)
final List<String> members =
Arrays.asList(“Ohshima”, “Hirose”, “Nancii”,
“Tanaka”, “Chen”, “Takano”);
members.forEach(System.out.println);
• そんなときのためのラムダ式
• さえいらない(メソッド参照)
メンバーを それぞれ 標準出力に出す
メソッド参照
• http://www.atmarkit.co.jp/ait/
articles/1407/28/news023_3.h
tml
• (例によって手抜きでスミマセン
……)
まずは forEach の
例を紹介しましたが、
Stream API と組
み合わせるとこのラ
ムダ式の簡潔さが大
活躍します
次回以降を
乞うご期待
白状すると
DataSpider の中
にこの forEach で
置き換えられる
コードがなかなか
見つかりません
たとえばこれがい
けるかな……
と思ったのですが
List<CellToWrite[]> rows =
Arrays.asList(new CellToWrite[][] {
new CellToWrite[neededColumnsCount]
});
for (IntermediateCellData cell : data) {
int row = cell.rowIndex - minRow;
int column = cell.columnIndex - minColumn;
rows.get(row)[column] = new CellToWrite(
cell.address, cell.column, createWriteOption(cell));
}
List<CellToWrite[]> rows =
Arrays.asList(new CellToWrite[][] {
new CellToWrite[neededColumnsCount]
});
data.forEach(cell -> {
int row = cell.rowIndex - minRow;
int column = cell.columnIndex - minColumn;
rows.get(row)[column] = new CellToWrite(
cell.address, cell.column, createWriteOption(cell));
});
• これだけだと
大して簡潔にならないし、しかも
List<CellToWrite[]> rows =
Arrays.asList(new CellToWrite[][] {
new CellToWrite[neededColumnsCount]
});
data.forEach(cell -> {
int row = cell.rowIndex - minRow;
int column = cell.columnIndex - minColumn;
rows.get(row)[column] = new CellToWrite(
cell.address, cell.column, createWriteOption(cell));
});
• 言うほど読みやすくならない
• ていうかコンパイルエラー処理されない例外の型 Exception
List<CellToWrite[]> rows =
Arrays.asList(new CellToWrite[][] {
new CellToWrite[neededColumnsCount]
});
data.forEach(cell -> {
int row = cell.rowIndex - minRow;
int column = cell.columnIndex - minColumn;
rows.get(row)[column] = new CellToWrite(
cell.address, cell.column, createWriteOption(cell));
});
• 言うほど読みやすくならない
• ていうかコンパイルエラー
処理されない例外の型 Exception
Iterable#forEach(Consumer<? super T> action)
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
public CellToWrite(
String position, Column column,
Excel2007WriteOption option)
throws Exception {
List<CellToWrite[]> rows =
Arrays.asList(new CellToWrite[][] {
new CellToWrite[neededColumnsCount]
});
data.forEach(cell -> {
int row = cell.rowIndex - minRow;
int column = cell.columnIndex - minColumn;
try {
rows.get(row)[column] = new CellToWrite(
cell.address, cell.column,
createWriteOption(cell));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
モサすぎる
(注意)
これはラムダ式固有の問題というわけではなく、あ
くまで forEach と関数型インタフェース周辺の問
題です。ただし、Stream API(と関数型インタ
フェース)を使用する際にもこの問題は頻出すると
思われます
関数型のコードと
親和性の高い設計
や API 設計に少し
ずつ寄せていく努
力が必要になりそ
うです
(XML
Framework と
Stream API との
可能性も含めた親
和性が気になると
ころ……)
次回以降が
楽しみです

More Related Content

What's hot

Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Yoshio Terada
 
ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)taskie
 
Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)AyakaNishiyama
 
ユニットテストの保守性を作りこむ, xpjugkansai2011
ユニットテストの保守性を作りこむ, xpjugkansai2011ユニットテストの保守性を作りこむ, xpjugkansai2011
ユニットテストの保守性を作りこむ, xpjugkansai2011H Iseri
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPIAkihiro Ikezoe
 
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」fukuoka.ex
 
自己結合Sqlクエリ検出ツールによるチューニングの提案
自己結合Sqlクエリ検出ツールによるチューニングの提案自己結合Sqlクエリ検出ツールによるチューニングの提案
自己結合Sqlクエリ検出ツールによるチューニングの提案拓也 岸本
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition心 谷本
 
DBFlute2017フェスLT資料
DBFlute2017フェスLT資料DBFlute2017フェスLT資料
DBFlute2017フェスLT資料shogokataoka
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルなおき きしだ
 
Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】Yukiko Kato
 
Java8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるJava8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるShinya Mochida
 
Processing.jsでおうちハック
Processing.jsでおうちハックProcessing.jsでおうちハック
Processing.jsでおうちハックsonycsl
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriYuta Okamoto
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門dcubeio
 

What's hot (20)

Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 
ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)ECMAScript 6 Features(PDF 版)
ECMAScript 6 Features(PDF 版)
 
講座Java入門
講座Java入門講座Java入門
講座Java入門
 
Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)
 
ユニットテストの保守性を作りこむ, xpjugkansai2011
ユニットテストの保守性を作りこむ, xpjugkansai2011ユニットテストの保守性を作りこむ, xpjugkansai2011
ユニットテストの保守性を作りこむ, xpjugkansai2011
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI
 
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
 
Java8勉強会
Java8勉強会Java8勉強会
Java8勉強会
 
自己結合Sqlクエリ検出ツールによるチューニングの提案
自己結合Sqlクエリ検出ツールによるチューニングの提案自己結合Sqlクエリ検出ツールによるチューニングの提案
自己結合Sqlクエリ検出ツールによるチューニングの提案
 
Junit4
Junit4Junit4
Junit4
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
 
DBFlute2017フェスLT資料
DBFlute2017フェスLT資料DBFlute2017フェスLT資料
DBFlute2017フェスLT資料
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイル
 
Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】
 
Java8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみるJava8のstreamをダラダラまとめてみる
Java8のstreamをダラダラまとめてみる
 
Processing.jsでおうちハック
Processing.jsでおうちハックProcessing.jsでおうちハック
Processing.jsでおうちハック
 
null使ったら負け福岡版
null使ったら負け福岡版null使ったら負け福岡版
null使ったら負け福岡版
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門
 

Viewers also liked

ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月Taku Miyakawa
 
Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Appresso Engineering Team
 
Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Appresso Engineering Team
 
Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Appresso Engineering Team
 
JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文Appresso Engineering Team
 
Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Appresso Engineering Team
 
マルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Executionマルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded ExecutionAppresso Engineering Team
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと心 谷本
 

Viewers also liked (20)

Effective Java 輪読会 項目60-62
Effective Java 輪読会 項目60-62Effective Java 輪読会 項目60-62
Effective Java 輪読会 項目60-62
 
ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月
 
Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7Effective java 輪読会 第2章 項目5,6,7
Effective java 輪読会 第2章 項目5,6,7
 
Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22Effective java 輪読会 第4章 項目18-22
Effective java 輪読会 第4章 項目18-22
 
Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4Effective java 輪読会 第2章 項目1,2,3,4
Effective java 輪読会 第2章 項目1,2,3,4
 
JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文JavaScript 勉強会 ― 変数・演算子・文
JavaScript 勉強会 ― 変数・演算子・文
 
Effective Java 輪読会 項目69-70追加
Effective Java 輪読会 項目69-70追加Effective Java 輪読会 項目69-70追加
Effective Java 輪読会 項目69-70追加
 
Effective Java 輪読会 項目63-65
Effective Java 輪読会 項目63-65Effective Java 輪読会 項目63-65
Effective Java 輪読会 項目63-65
 
Effective Java 輪読会 項目69-70
Effective Java 輪読会 項目69-70Effective Java 輪読会 項目69-70
Effective Java 輪読会 項目69-70
 
JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値JavaScript 勉強会 ― 型と値
JavaScript 勉強会 ― 型と値
 
Effective Java 輪読会 項目71-73
Effective Java 輪読会 項目71-73Effective Java 輪読会 項目71-73
Effective Java 輪読会 項目71-73
 
Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56Effective Java 輪読会 項目53-56
Effective Java 輪読会 項目53-56
 
Effective Java 輪読会 項目66-68
Effective Java 輪読会 項目66-68Effective Java 輪読会 項目66-68
Effective Java 輪読会 項目66-68
 
Effective Java 輪読会 項目74-75
Effective Java 輪読会 項目74-75Effective Java 輪読会 項目74-75
Effective Java 輪読会 項目74-75
 
Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44Effective Java 輪読会 第7章 項目43-44
Effective Java 輪読会 第7章 項目43-44
 
Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48
 
Effective Java 輪読会 項目77-78
Effective Java 輪読会 項目77-78Effective Java 輪読会 項目77-78
Effective Java 輪読会 項目77-78
 
Effective Java 輪読会 項目49-52
Effective Java 輪読会 項目49-52Effective Java 輪読会 項目49-52
Effective Java 輪読会 項目49-52
 
マルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Executionマルチスレッド デザインパターン ― Single Threaded Execution
マルチスレッド デザインパターン ― Single Threaded Execution
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと
 

Similar to 20150302 java8 第一回_ラムダ式(1)

Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generatorOda Shinsuke
 
オープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングオープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングSho Okada
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へonozaty
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~Fujio Kojima
 
探検!SwiftyJSON
探検!SwiftyJSON探検!SwiftyJSON
探検!SwiftyJSONYuka Ezura
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Uehara Junji
 
Unit test in android
Unit test in androidUnit test in android
Unit test in androidTatsuya Maki
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccYujiSoftware
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 

Similar to 20150302 java8 第一回_ラムダ式(1) (20)

Scala東北紹介
Scala東北紹介Scala東北紹介
Scala東北紹介
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generator
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
Starting java fx
Starting java fxStarting java fx
Starting java fx
 
オープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングオープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミング
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へ
 
Akka Unit Testing
Akka Unit TestingAkka Unit Testing
Akka Unit Testing
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
探検!SwiftyJSON
探検!SwiftyJSON探検!SwiftyJSON
探検!SwiftyJSON
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
 
Unit test in android
Unit test in androidUnit test in android
Unit test in android
 
Cubby 2006-08-23
Cubby 2006-08-23Cubby 2006-08-23
Cubby 2006-08-23
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 

More from Appresso Engineering Team

More from Appresso Engineering Team (12)

Java Day Tokyo 2014 まとめ (chen)
Java Day Tokyo 2014 まとめ (chen)Java Day Tokyo 2014 まとめ (chen)
Java Day Tokyo 2014 まとめ (chen)
 
Effective java 輪読会 項目57-59
Effective java 輪読会 項目57-59Effective java 輪読会 項目57-59
Effective java 輪読会 項目57-59
 
Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42Effective Java 輪読会 第7章 項目41-42
Effective Java 輪読会 第7章 項目41-42
 
Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40Effective Java 輪読会 第7章 項目38-40
Effective Java 輪読会 第7章 項目38-40
 
Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37Effective Java 輪読会 第6章 項目35-37
Effective Java 輪読会 第6章 項目35-37
 
Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34
 
Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31Effective java 輪読会 第6章 項目30-31
Effective java 輪読会 第6章 項目30-31
 
Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29Effective java 輪読会 第5章 項目26-29
Effective java 輪読会 第5章 項目26-29
 
Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25Effective java 輪読会 第5章 項目23-25
Effective java 輪読会 第5章 項目23-25
 
Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17Effective Java 輪読会 第4章 項目13-17
Effective Java 輪読会 第4章 項目13-17
 
Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12Effective java 輪読会 第3章 項目11, 12
Effective java 輪読会 第3章 項目11, 12
 
Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10Effective java 輪読会 第3章 項目8,9,10
Effective java 輪読会 第3章 項目8,9,10
 

20150302 java8 第一回_ラムダ式(1)

  • 1. Java 8 勉強会 第一回 ラムダ式 (1) 2015/3/2 開発部 3G 野口光太郎
  • 2.
  • 4. Java 8 導入予定 • Thunderbus • 1.0 で導入済(8u31) • PIMSYNC • 2.2 で導入予定 • DataSpider Servista • 4.0 で導入予定
  • 5. Java 8 の新機能 • ラムダ式 • Stream API • Date and Time API • JavaFX 8 • etc…
  • 6. Java 8 の新機能 • ラムダ式 • Stream API • Date and Time API • JavaFX 8 • etc…
  • 8. Java 8 勉強会 第一回 ラムダ式 (1) 2015/3/2 開発部 3G 野口光太郎
  • 11. ラムダ式とは • 匿名関数の簡略な記法 • Java 8(2014/3)で導入 • 取り立てて新しい概念ではない • C++11(2011 年) • C# 3.0(2008 年) • Lisp(ざっと 50 年くらい前)
  • 12. ラムダ式とは • 匿名関数の簡略な記法 • Java 8(2014/3)で導入 • 取り立てて新しい概念ではない • C++11(2011 年) • C# 3.0(2008 年) • Lisp(ざっと 50 年くらい前)
  • 14. 匿名関数とは • 匿名の関数 • 要するにこれのこと List<Integer> numbers = Arrays.asList(1, 1, 2, 3, 5); Collections.sort(numbers, new Comparator<Integer>() { @Override public int compare(Integer i1, Integer i2) { return i2 - i1; } });
  • 15. 匿名関数の簡略な記法 • こう書ける List numbers = Arrays.asList(1, 1, 2, 3, 5); Collections.sort(numbers, (i1, i2) -> i2 - i1);
  • 17. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, new Assertion() { @Override public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); }
  • 18. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, new Assertion() { @Override public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); }
  • 19. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, new Assertion() { @Override public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); } ノイズ ・new ・Assertion() ・@Override ・public ・void ・call テストの内容にとっては全部どうでもいい
  • 20. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, new Assertion() { @Override public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); }
  • 21. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, (expectedSheet, actualSheet, row, column) -> { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); } • こう書ける
  • 22. Excel アダプタのテスト コードの例(Before) • こういうのも private interface Assertion { public void call(Sheet expectedSheet, Sheet actualSheet, int row, int column) throws Exception; } private void assertDataAndFormat(String expectedExcelFileName, String sheetName, int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex) throws Exception { assertWithExpectedExcelFile( expectedExcelFileName, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, (expectedSheet, actualSheet, row, column) -> { Cell expetedCell = expectedSheet.getCell(column, row); Cell actualCell = actualSheet.getCell(column, row); assertEquals(expetedCell.getContents(), actualCell.getContents()); assertEquals(expetedCell.getType().toString(), actualCell.getType().toString()); assertEquals(expetedCell.getCellFormat().getFormat().getFormatString(), actualCell.getCellFormat().getFormat().getFormatString()); AssertUtil.assertCellFormatByJExcelApi( expetedCell.getCellFormat(), actualCell.getCellFormat()); } } ); } Excel アダプタのテスト コードの例(After) (匿名関数) • こう書ける • メソッドに関数を直接渡せる
  • 24. xxx アダプタのテスト コードの例(Before) • こういうのも @Test public void ソート_標準カラム_文書管理番号_昇順() throws Exception { ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2){ return o1.getDocNum() - o2.getDocNum(); } }); }
  • 25. xxx アダプタのテスト コードの例(Before) • こういうのも @Test public void ソート_標準カラム_文書管理番号_昇順() throws Exception { ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { return o1.getDocNum() - o2.getDocNum(); } }); } @Test public void ソート_標準カラム_文書管理番号_降順() throws Exception { ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { return o2.getDocNum() - o1.getDocNum(); } }); } 1
  • 26. @Test public void ソート_標準カラム_文書名_昇順() throws Exception { ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getDocName(); String v2 = o2.getDocName(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_文書名_降順() throws Exception { ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getDocName(); String v2 = o2.getDocName(); return compareNull(v2, v1); } }); } @Test public void ソート_標準カラム_コンピューター名_昇順() throws Exception { ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getComputerName(); String v2 = o2.getComputerName(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_コンピューター名_降順() throws Exception { ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getComputerName(); String v2 = o2.getComputerName(); return compareNull(v2, v1); } }); } 2
  • 27. @Test public void ソート_標準カラム_ユーザー名_昇順() throws Exception { ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getUserName(); String v2 = o2.getUserName(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_ユーザー名_降順() throws Exception { ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getUserName(); String v2 = o2.getUserName(); return compareNull(v2, v1); } }); } @Test public void ソート_標準カラム_印刷プリンター名_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getPrinterName(); String v2 = o2.getPrinterName(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_印刷プリンター名_降順() throws Exception { ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getPrinterName(); String v2 = o2.getPrinterName(); return compareNull(v2, v1); } }); } 3
  • 28. @Test public void ソート_標準カラム_印刷プリンターグループ名_昇順() throws Exception { ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getPrinterGroupName(); String v2 = o2.getPrinterGroupName(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_印刷プリンターグループ名_降順() throws Exception { ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { String v1 = o1.getPrinterGroupName(); String v2 = o2.getPrinterGroupName(); return compareNull(v2, v1); } }); } @Test public void ソート_標準カラム_スプール開始時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getSpoolStartTime(); Date v2 = o2.getSpoolStartTime(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_スプール開始時刻_降順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getSpoolStartTime(); Date v2 = o2.getSpoolStartTime(); return compareNull(v2, v1); } }); } 4
  • 29. @Test public void ソート_標準カラム_スプール終了時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getSpoolEndTime(); Date v2 = o2.getSpoolEndTime(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_スプール終了時刻_降順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getSpoolEndTime(); Date v2 = o2.getSpoolEndTime(); return compareNull(v2, v1); } }); } @Test public void ソート_標準カラム_印刷開始時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getPrintStartTime(); Date v2 = o2.getPrintStartTime(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_印刷開始時刻_降順() throws Exception { ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getPrintStartTime(); Date v2 = o2.getPrintStartTime(); return compareNull(v2, v1); } }); } 5
  • 30. @Test public void ソート_標準カラム_印刷終了時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getPrintEndTime(); Date v2 = o2.getPrintEndTime(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_印刷終了時刻_降順() throws Exception { ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getPrintEndTime(); Date v2 = o2.getPrintEndTime(); return compareNull(v2, v1); } }); } @Test public void ソート_標準カラム_最終更新時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 0, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getUpdateTime(); Date v2 = o2.getUpdateTime(); return compareNull(v1, v2); } }); } @Test public void ソート_標準カラム_最終更新時刻_降順() throws Exception { ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 1, new Comparator() { @Override public int compare(XXXDocument o1, XXXDocument o2) { Date v1 = o1.getUpdateTime(); Date v2 = o2.getUpdateTime(); return compareNull(v2, v1); } }); } 6
  • 32. • こう書ける @Test public void ソート_標準カラム_文書管理番号_昇順() throws Exception { ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 0, (o1, o2) -> o1.getDocNum() - o2.getDocNum()); } @Test public void ソート_標準カラム_文書管理番号_降順() throws Exception { ソート(STANDARD_COLUMN, MANAGE_NUM, TAG_DOC_NUM, 1, (o1, o2) -> o2.getDocNum() - o1.getDocNum()); } @Test public void ソート_標準カラム_文書名_昇順() throws Exception { ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 0, (o1, o2) -> compareNull(o1.getDocName(), o2.getDocName()); } @Test public void ソート_標準カラム_文書名_降順() throws Exception { ソート(STANDARD_COLUMN, DOC_NAME, TAG_DOC_NAME, 1, (o1, o2) -> compareNull(o2.getDocName(), o1.getDocName()); } @Test public void ソート_標準カラム_コンピューター名_昇順() throws Exception { ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 0, (o1, o2) -> compareNull(o1.getComputerName(), o2.getComputerName()); } xxx アダプタのテスト コードの例(After) 1
  • 33. @Test public void ソート_標準カラム_コンピューター名_降順() throws Exception { ソート(STANDARD_COLUMN, COMPUTER_NAME, TAG_COMPUTER_NAME, 1, (o1, o2) -> compareNull(o2.getComputerName(), o1.getComputerName()); } @Test public void ソート_標準カラム_ユーザー名_昇順() throws Exception { ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 0, (o1, o2) -> compareNull(o1.getUserName(), o2.getUserName()); } @Test public void ソート_標準カラム_ユーザー名_降順() throws Exception { ソート(STANDARD_COLUMN, USER_NAME, TAG_USER_NAME, 1, (o1, o2) -> compareNull(o2.getUserName(), o1.getUserName()); } @Test public void ソート_標準カラム_印刷プリンター名_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 0, (o1, o2) -> compareNull(o1.getPrinterName(), o2.getPrinterName()); } @Test public void ソート_標準カラム_印刷プリンター名_降順() throws Exception { ソート(STANDARD_COLUMN, PRINTER_NAME, TAG_PRINTER_NAME, 1, (o1, o2) -> compareNull(o2.getPrinterName(), o1.getPrinterName()); } @Test public void ソート_標準カラム_印刷プリンターグループ名_昇順() throws Exception { ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 0, (o1, o2) -> compareNull(o1.getPrinterGroupName(), o2.getPrinterGroupName()); } @Test public void ソート_標準カラム_印刷プリンターグループ名_降順() throws Exception { ソート(STANDARD_COLUMN, GROUP_NAME, TAG_PRINTER_GROUP_NAME, 1, (o1, o2) -> compareNull(o2.getPrinterGroupName(), o1.getPrinterGroupName()); } @Test public void ソート_標準カラム_スプール開始時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 0, (o1, o2) -> compareNull(o1.getSpoolStartTime(), o2.getSpoolStartTime()); } @Test public void ソート_標準カラム_スプール開始時刻_降順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_START_TIME, TAG_SPOOL_START_TIME, 1, (o1, o2) -> compareNull(o2.getSpoolStartTime(), o1.getSpoolStartTime()); } @Test public void ソート_標準カラム_スプール終了時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 0, (o1, o2) -> compareNull(o1.getSpoolEndTime(), o2.getSpoolEndTime()); } 2
  • 34. @Test public void ソート_標準カラム_スプール終了時刻_降順() throws Exception { ソート(STANDARD_COLUMN, SPOOL_END_TIME, TAG_SPOOL_END_TIME, 1, (o1, o2) -> compareNull(o2.getSpoolEndTime(), o1.getSpoolEndTime()); } @Test public void ソート_標準カラム_印刷開始時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINT_START_TIME, TAG_PRINT_START_TIME, 0, (o1, o2) -> compareNull(o1.getPrintStartTime(), o2.getPrintStartTime()); } @Test public void ソート_標準カラム_印刷開始時刻_降順() throws Exception { (o1, o2) -> compareNull(o2.getPrintStartTime(), o1.getPrintStartTime()); } @Test public void ソート_標準カラム_印刷終了時刻_昇順() throws Exception { ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 0, (o1, o2) -> compareNull(o1.getPrintEndTime(), o2.getPrintEndTime()); } @Test public void ソート_標準カラム_印刷終了時刻_降順() throws Exception { ソート(STANDARD_COLUMN, PRINT_END_TIME, TAG_PRINT_END_TIME, 1, (o1, o2) -> compareNull(o2.getPrintEndTime(), o1.getPrintEndTime()); } @Test public void ソート_標準カラム_最終更新時刻_昇順() throws Exception { (o1, o2) -> compareNull(o1.getUpdateTime(), o2.getUpdateTime()); } @Test public void ソート_標準カラム_最終更新時刻_降順() throws Exception { ソート(STANDARD_COLUMN, UPDATE_TIME, TAG_UPDATE_TIME, 1, (o1, o2) -> compareNull(o2.getUpdateTime(), o1.getUpdateTime()); } 3
  • 36. テストケース数 : 22 → 22 (100%) ページ数 : 6 → 3 (50%) 行数 : 247→107 (43%)
  • 37. 嬉しい • ノイズの減少 • 本質的なコードだけが残る • 一覧性の向上 • たとえばテストがスペックに近 づく • 気がする
  • 42. 開かれる 関数型スタイルへの道 • 私たちが愛する • 不変性 • 実装の隠蔽 • ドキュメントとしてのコード • 遅延評価 • 並列化
  • 45. 2. ラムダ式を書く • 何をラムダ式で書けるのか • どのようにラムダ式を書けるのか • いつラムダ式を書くべきか • ラムダ式さえ書かなくてもよいと きもある
  • 46. 2. ラムダ式を書く • 何をラムダ式で書けるのか • どのようにラムダ式を書けるのか • いつラムダ式を書くべきか • ラムダ式さえ書かなくてもよいと きもある
  • 49. 関数型インタフェース • 実装が必要なメソッドを一つだけ 持つインタフェース • 実装が必要なメソッド? → 未実装の abstract メソッド • 唯一の abstract メソッド以外に、 static メソッドや default メソッ ドが定義されている場合もある
  • 50. 関数型インタフェースの例 • ~ JDK 7 • Runnable • Callable • Comparator • JDK 8 ~ • Predicate • Consumer • Supplier
  • 51. 関数型インタフェースの例 • ~ JDK 7 • Runnable • Callable • Comparator • JDK 8 ~ • Predicate • Consumer • Supplier
  • 52. JDK 7 までの Comparator public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
  • 53. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 54. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 55. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 56. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 57. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 58. JDK 8 の Comparator @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } ... (6 default methods) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } ... (8 static methods) }
  • 59. @FunctionalInterface • 関数型インタフェースにつけるこ とができるアノテーション • つけなくてもよい • つけるとコンパイラが関数型イ ンタフェースかどうかチェック してくれる • 人間の目にもやさしい
  • 60. デフォルトメソッド • インタフェースに実装を定義でき る記法 • default キーワードを記述 • 後方互換性を保ちながらインタ フェースを拡張するために導入 された • 詳細は次回……。
  • 61. 2. ラムダ式を書く • 何をラムダ式で書けるのか • どのようにラムダ式を書けるのか • いつラムダ式を書くべきか • ラムダ式さえ書かなくてもよいと きもある
  • 64. ラムダ式の記法 • ( 実装するメソッドの引数 ) -> { 処理 } • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (Integer o1, Integer o2) -> { return o1 – o2 }
  • 65. ラムダ式の記法 • ( 実装するメソッドの引数 ) -> { 処理 } • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (Integer o1, Integer o2) -> { return o1 – o2 }
  • 66. ラムダ式の記法 • ( 実装するメソッドの引数 ) -> { 処理 } • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (Integer o1, Integer o2) -> { return o1 – o2; }
  • 68. ラムダ式の記法 (省略前) • ( 実装するメソッドの引数 ) -> { 処理 } • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (Integer o1, Integer o2) -> { return o1 – o2; }
  • 69. ラムダ式の記法 (省略 1) • 型推論 • 例 : Comparator の場合 int compare(Integer o1, Integer o2) に対して (Integer o1, Integer o2) -> { return o1 – o2; }
  • 70. ラムダ式の記法 (省略 1) • 型推論 • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (o1, o2) -> { return o1 – o2; }
  • 71. ラムダ式の記法 (省略 2) • 波括弧(「{}」)と return の省略 • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (o1, o2) -> { return o1 – o2; }
  • 72. ラムダ式の記法 (省略 2) • 波括弧(「{}」)と return の省略 • 例 : Comparator<Integer> の場合 int compare(Integer o1, Integer o2) に対して (o1, o2) -> o1 – o2
  • 73. ラムダ式の記法 (省略 3) • 丸括弧(「()」)の省略 • 丸括弧が省略できるのは、メソッドの引数 が 1 つだけの場合
  • 74. ラムダ式の記法 (省略 3) • 丸括弧(「()」)の省略前 • 例 : Predicate<Integer> の場合 boolean test(Integer t) に対して (Integer t) -> { return (t > 100); }
  • 75. ラムダ式の記法 (省略 3) • 丸括弧(「()」)の省略後 • 例 : Predicate<Integer> の場合 boolean test(Integer t) に対して (Integer t) -> { return (t > 100); }
  • 76. ラムダ式の記法 (省略 3) • 丸括弧(「()」)の省略後 • 例 : Predicate<Integer> の場合 boolean test(Integer t) に対して t -> { return (t > 100); }
  • 77. ラムダ式の記法 (省略 3) • さらに省略すると • 例 : Predicate<Integer> の場合 boolean test(Integer t) に対して t -> { return (t > 100); }
  • 78. ラムダ式の記法 (省略 3) • さらに省略すると • 例 : Predicate<Integer> の場合 boolean test(Integer t) に対して t -> t > 100
  • 80. ラムダ式の記法 (引数なし) • メソッドに引数がない場合 丸括弧のみ記述する • 例 : Callable<Integer> の場合 Integer call() に対して () -> { return 100; }
  • 81. ラムダ式の記法 (引数なし) • メソッドに引数がない場合 丸括弧のみ記述する • 例 : Callable<Integer> の場合 Integer call() に対して () -> { return 100; }
  • 82. ラムダ式の記法 (実質的に final) • 実質的に final • 匿名クラスでは、メソッド内で参照 するローカル変数には final キー ワードが必要 • ラムダ式では、その変数について final と同等に扱っていれば、final キーワードは不要
  • 84. 2. ラムダ式を書く • 何をラムダ式で書けるのか • どのようにラムダ式を書けるのか • いつラムダ式を書くべきか • ラムダ式さえ書かなくてもよいと きもある
  • 87. 書けるところなら どこでもラムダ式を書く • ラムダ式は関数型インタフェースの略 記法にすぎない • むずかしくない • こわくない • ラムダ式はノイズを減らして本質を残 す • 簡潔で読みやすいコードをつくる
  • 91. 2. ラムダ式を書く • 何をラムダ式で書けるのか • どのようにラムダ式を書けるのか • いつラムダ式を書くべきか • ラムダ式さえ書かなくてもよいと きもある
  • 92. ラムダ式さえ書かなくて もよいときもある • メソッド参照 • ざっくり言うとこう書ける仕組み • Before : name -> System.out.println(name) • After : System.out.println • のちほどもうちょっと説明します
  • 94. forEach による イテレーション • ラムダ式の活用例 • イテレーションが高級になっていく歴 史 • for (int i = 0; i < list.size(); i++) • for (String s : list) • list.forEach()
  • 95. forEach による イテレーション • ラムダ式の活用例 • イテレーションが高級になっていく歴 史の第三段階 • for (int i = 0; i < list.size(); i++) • for (String s : list) • list.forEach()
  • 96. 原始 for 文 final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); for (int i = 0; i < members.size(); i++) { System.out.println(members.get(i)); }
  • 97. 原始 for 文 final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); for (int i = 0; i < members.size(); i++) { System.out.println(members.get(i)); } • ノイズが多い • OBOE や変数の取り違えが 起こりかねない
  • 98. 拡張 for 文(Java 5~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); for (String member : members) { System.out.println(member); }
  • 99. 拡張 for 文(Java 5~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); for (String member : members) { System.out.println(member); } • もう OBOE は起こらない • が、まだ冗長だ……。
  • 100. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); Members.forEach(new Consumer<String>() { public void accept(final String name) { System.out.println(name); } });
  • 101. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach(new Consumer<String>() { public void accept(final String name) { System.out.println(name); } }); • ウッけっこうノイズが多いような ……
  • 102. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach(new Consumer<String>() { public void accept(final String name) { System.out.println(name); } }); • そんなときのためのラムダ式 • 1
  • 103. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach( (final String name) -> System.out.println(name)); • そんなときのためのラムダ式 • 1
  • 104. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach( (final String name) -> System.out.println(name)); • そんなときのためのラムダ式 • 2
  • 105. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach( name -> System.out.println(name)); • そんなときのためのラムダ式 • 2
  • 106. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach( name -> System.out.println(name)); • そんなときのためのラムダ式 • さえいらない(メソッド参照)
  • 107. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach(System.out.println); • そんなときのためのラムダ式 • さえいらない(メソッド参照)
  • 108. forEach(Java 8~) final List<String> members = Arrays.asList(“Ohshima”, “Hirose”, “Nancii”, “Tanaka”, “Chen”, “Takano”); members.forEach(System.out.println); • そんなときのためのラムダ式 • さえいらない(メソッド参照) メンバーを それぞれ 標準出力に出す
  • 110. まずは forEach の 例を紹介しましたが、 Stream API と組 み合わせるとこのラ ムダ式の簡潔さが大 活躍します
  • 113. DataSpider の中 にこの forEach で 置き換えられる コードがなかなか 見つかりません
  • 115. List<CellToWrite[]> rows = Arrays.asList(new CellToWrite[][] { new CellToWrite[neededColumnsCount] }); for (IntermediateCellData cell : data) { int row = cell.rowIndex - minRow; int column = cell.columnIndex - minColumn; rows.get(row)[column] = new CellToWrite( cell.address, cell.column, createWriteOption(cell)); }
  • 116. List<CellToWrite[]> rows = Arrays.asList(new CellToWrite[][] { new CellToWrite[neededColumnsCount] }); data.forEach(cell -> { int row = cell.rowIndex - minRow; int column = cell.columnIndex - minColumn; rows.get(row)[column] = new CellToWrite( cell.address, cell.column, createWriteOption(cell)); }); • これだけだと 大して簡潔にならないし、しかも
  • 117. List<CellToWrite[]> rows = Arrays.asList(new CellToWrite[][] { new CellToWrite[neededColumnsCount] }); data.forEach(cell -> { int row = cell.rowIndex - minRow; int column = cell.columnIndex - minColumn; rows.get(row)[column] = new CellToWrite( cell.address, cell.column, createWriteOption(cell)); }); • 言うほど読みやすくならない • ていうかコンパイルエラー処理されない例外の型 Exception
  • 118. List<CellToWrite[]> rows = Arrays.asList(new CellToWrite[][] { new CellToWrite[neededColumnsCount] }); data.forEach(cell -> { int row = cell.rowIndex - minRow; int column = cell.columnIndex - minColumn; rows.get(row)[column] = new CellToWrite( cell.address, cell.column, createWriteOption(cell)); }); • 言うほど読みやすくならない • ていうかコンパイルエラー 処理されない例外の型 Exception Iterable#forEach(Consumer<? super T> action) @FunctionalInterface public interface Consumer<T> { void accept(T t); } public CellToWrite( String position, Column column, Excel2007WriteOption option) throws Exception {
  • 119. List<CellToWrite[]> rows = Arrays.asList(new CellToWrite[][] { new CellToWrite[neededColumnsCount] }); data.forEach(cell -> { int row = cell.rowIndex - minRow; int column = cell.columnIndex - minColumn; try { rows.get(row)[column] = new CellToWrite( cell.address, cell.column, createWriteOption(cell)); } catch (Exception e) { throw new RuntimeException(e); } });
  • 121. (注意) これはラムダ式固有の問題というわけではなく、あ くまで forEach と関数型インタフェース周辺の問 題です。ただし、Stream API(と関数型インタ フェース)を使用する際にもこの問題は頻出すると 思われます
  • 123. (XML Framework と Stream API との 可能性も含めた親 和性が気になると ころ……)