SlideShare ist ein Scribd-Unternehmen logo
1 von 49
CHAPTER 5 
Advanced Collections and Collectors 
Kei Takinami
Method References 
メソッド参照 
Java8 から「::」演算子を使ってメソッドを関数オブジェクトとし 
て参照することができるようになった。 
// インスタンスメソッドString#length() 
Function<String, Integer> func1 = String::length; 
assert func1.apply("Java 8") == 6; 
インターフェイス:Function<T,R> 
実装するメソッド:R apply(T t) 
概要:実装するメソッドは、引数としてTを受け取り、結果としてRを返すものになる。 
メモ
Example1 
例) アーティストの名前の一覧を取得したい場合。 
ラムダ形式の場合 
artist -> artist.getName() 
メモ 
あくまでメソッド参照なので、最後の()はいらない。 
メソッド参照の場合 
Artist::getName
Example2 
コンストラクタでも使える 
ラムダ形式の場合 
(name, nationality) -> new Artist(name, nationality) 
メソッド参照の場合 
Artist::new
メソッド参照の形式 
クラス名::メソッド名(staticメソッド) 
インスタンス名::メソッド名(インスタンスメソッド) 
// staticメソッドの場合 
public class Sample { 
public static void main(String[] args) { 
Function<String, String> func2 = Sample::add; 
System.out.println(func2.apply(“test02")); // => [☆ test02 ☆] 
} 
public static String add(String value) { 
return “[☆" + value + " ☆]"; 
} 
}
// インスタンスメソッドの場合 
public class Sample { 
public static void main(String[] args) { 
Sample sample = new Sample(); 
Function<String, String> func1 = sample::add; 
System.out.println(func1.apply(“test01")); // => [☆ test01 ☆] 
} 
public static String add(String value) { 
return “[☆" + value + " ☆]"; 
} 
}
Element Ordering 
要素の順番 
順序が定義されたCollectionからStreamを生成するときには 
そのStreamも順序を持つ。 
例) リストとStreamから生成された同じリストを比較 
List<Integer> numbers = asList(1,2,3,4); 
List<Integer> sameOrder = numbers.stream() 
.collect(toList()); 
assertEquals(numbers, sameOrder); // => これは必ずOK
逆に順序が定義されてないCollection(例えばHashSet)から 
Streamを生成するときには 
そのStreamも順序を持たない。 
例) SetとStreamから生成された同じリストを比較 
Set<Integer> numbers = new HashSet<>(asList(4,3,2,1)); 
List<Integer> sameOrder = numbers.stream() 
.collect(toList()); 
// NGになる場合がある 
assertEquals(asList(4,3,2,1) sameOrder);
Streamの役割 
Streamの役割はあるCollectionを他のCollectionへ変換するだけじゃない。 
データに対していろんな処理ができるようにすることでもある。 
例) 順番 
Set<Integer> numbers = new HashSet<>(asList(4,3,2,1)); 
List<Integer> sameOrder = numbers.stream() 
.sorted() 
.collect(toList()); 
// 前回と違って今回は必ずOK 
assertEquals(asList(1,2,3,4), sameOrder);
この順序は途中で処理を入れても維持される。 
例えばmap処理を途中に入れてみる。 
例) map処理で対象のリストをインクリメント 
List<Integer> numbers = asList(1,2,3,4); 
List<Integer> stillOrdered = numbers.stream() 
.map(x -> x + 1) 
.collect(toList()); 
assertEquals(asList(2,3,4,5), stillOrdered); // => 必ずOK
ただ、順序があるから必ずいいというわけではない。 
順序があることによってコストがかかることもある。 
そういう場合は、streamのunorderedメソッドを使用 
例) 前の例にunordered()を追加 
List<Integer> numbers = asList(1,2,3,4); 
List<Integer> stillOrdered = numbers.stream() 
.unordered() // 追加 
.map(x -> x + 1) 
.collect(toList()); 
assertEquals(asList(2,3,4,5), stillOrdered); // => 必ずOK 
メモ 
でも実際、filter,map,reduceは順序を維持した 
streamでもかなり高速に動作する。
並行処理の場合の順序 
parallelstreamのときだけはforEachは順番を 
保証しない。 
List<String> list = Arrays.asList("list1", "list2", "list3", "list4", "list5"); 
// 順番通りに表示=> list1, list2, list3, list4, list5 
list.stream().forEach(e -> System.out.println(e)); 
// ランダムに表示=> list3, list5, list4, list2, list1 
list.parallelStream().forEach(e -> System.out.println(e));
その場合は 
forEachOrdered(Consumer<? super T> action) 
List<String> list = Arrays.asList("list1", "list2", "list3", "list4", "list5"); 
// ランダムに表示=> list3, list5, list4, list2, list1 
list.parallelStream().forEach(e -> System.out.println(e)); 
// ランダムに表示=> list3, list5, list4, list2, list1 
list.parallelStream(). forEachOrdered(e -> System.out.println(e)); 
※注意 
順序は保証してくれるがパフォーマンスに影響があるので 
parallelstreamのときだけ使用するように。
Enter the Collector 
Collectorについて 
今までcollect(toList())を使ってListを作成しているけど 
mapもSetも使いたい。 
toSet()もtoMap()もtoCollectionもある 
例) toSet() 
Stream<String> s = Stream.of("a", "b", "c"); 
Set<String> set = s.collect(Collectors.toSet()); 
System.out.println(set);
ただ、toListのときも同様になんのListかわからない。 
自動的に最適な実クラスをStreamライブラリが設 
定していくれている。 
でも、ライブラリに任せないで自分でこのリストを使い 
たいときがある。 
例) TreeSetを指定 
stream().collect(toCollection(TreeSet::new));
collectorを使って、ひとつの値を取得することもできる。 
・maxBy 
・minBy 
public static Optional<Artist> biggestGroup(Stream<Artist> artists) { 
Function<Artist, Long> getCount = artist -> artist.getMembers() 
.count(); 
// 一番メンバーの多いバンドを返却 
return artists.collect(Collectors.maxBy(Comparator.comparing(getCount))); 
} 
To Values 
値の変換 
例) maxBy
もう少し簡単な例でmaxBy 
public static void sample01() { 
Stream<Integer> stream = Stream.of(1,2,3,4,5); 
Optional<Integer> maxNumber = 
stream.collect(Collectors.maxBy(Comparator.naturalOrder())); 
System.out.println(maxNumber.get()); 
} 
結果:5 
public static void sample02() { 
Stream<String> stream = Stream.of(“a”,“b”,“c”); // 文字列もOK 
Optional<String> maxNumber = 
stream .collect(Collectors.maxBy(Comparator.naturalOrder())); 
System.out.println(maxNumber.get()); 
} 
結果:c
他にも合計とか平均も出せる便利なものもある【1】 
// 合計を取得する場合=> summingInt 
public static void sample01() { 
Stream<Integer> stream = Stream.of(1,2,3,4,5); 
ToIntFunction<Integer> func = x -> x; 
// 合計を取得 
int sum = stream.collect(Collectors.summingInt(func)); 
// 15を出力 
System.out.println(sum); 
}
他にも合計とか平均も出せる便利なものもある【2】 
// オブジェクトを取得して、いろいろ計算 
public static void sample02() { 
Stream<Integer> numberStream = Stream.of(1,2,3,4,5); 
ToIntFunction<Integer> func = x -> x; 
// 集計オブジェクトを取得=> summarizingIntで取得 
IntSummaryStatistics sum = numberStream.collect(Collectors.summarizingInt(func)); 
// 合計を出力(15) 
System.out.println(sum.getSum()); 
// 要素数を出力(5) 
System.out.println(sum.getCount()); 
// 最大値を出力(5) 
System.out.println(sum.getMax()); 
// 最小値を出力(1) 
System.out.println(sum.getMin()); 
// 平均を出力(3) 
System.out.println(sum.getAverage()); 
}
Stream を使って条件毎に2つのコレクションに変換したい場合がある。 
例)アーティストのリストをソロとバンドで分けたい場合 
// partitioningByメソッドを使って分割 
public Map<Boolean, List<Artist>> bandsAndSolo(Stream<Artist> artists) { 
return artists.collect(Collectors.partitioningBy(artist -> artist.isSolo())); 
} 
結果:true=[SoloA,SoloB] false=[BandA] 
// メソッド参照を使った場合 
public Map<Boolean, List<Artist>> bandsAndSolo(Stream<Artist> artists) { 
return artists.collect(Collectors.partitioningBy(Artist::isSolo)); 
} 
Partitoning the Data 
データの分割 
partitioningByを使えばおk。 
引数にはPredicateを指定して、結果がtrueの場合とfalseの場合で場合分けしてくれる。 
インターフェイス:Predicate<T> 
実装するメソッド:boolean test(T t) 
概要:実装するメソッドは、引数としてTを受け取り、boolean値を結果として返すものになる。 
メモ
Grouping the Data 
データの分類 
true,falseで分けるんじゃなくて、他にどんな値でもできる。 
例えば、アルバムをアーティスト毎に分類したい場合。 
groupingByを使えばおk。 
引数にはClassifierを指定してあげる。 
public Map<Artist, List<Album>> albumsByArtist(Stream<Album> albums) { 
return albums.collect(Collectors.groupingBy(album -> album.getMainMusician())); 
}
Strings 
文字列 
Streamのデータを一般的に使う理由としては 
最終的に文字列を生成するため。(が多い)
例えばアーティスト名の一覧を出力したい場合 
Java8以前の場合Java8の場合 
public static void main(String args[]) { 
List<Artist> artists = new ArrayList<>(); 
artists.add(new Artist("George")); 
artists.add(new Artist("Harrison")); 
artists.add(new Artist("John")); 
StringBuilder builder = new StringBuilder("["); 
for (Artist artist : artists) { 
if (builder.length() > 1) { 
builder.append(","); 
} 
String name = artist.getName(); 
builder.append(name); 
} 
builder.append("]"); 
String result = builder.toString(); 
System.out.println(result); // => [George,Harrison,John] 
} 
public static void main(String args[]) { 
List<Artist> artists = new ArrayList<>(); 
artists.add(new Artist("George")); 
artists.add(new Artist("Harrison")); 
artists.add(new Artist("John")); 
String result = artists.stream() 
.map(Artist::getName) 
.collect(Collectors.joining(“,”,“[”,“]”)); 
System.out.println(result); // => [George,Harrison,John] 
} 
Collectors.joiningメソッドを使えばおk 
Collectors.joining(区切り文字,プレフィックス,サフィックス)といった感じ
Composing Collectors 
Collectorsの合成 
前回はアルバムをアーティスト毎に分類したが 
今回は各アーティストのアルバムの数を集計したい。 
一番簡単な方法は 
一度グルーピングしてから、アルバム数をカウント。
例)一度グルーピングしてから、アルバム数をカウント。 
// アーティスト毎にグルーピング 
Map<Artist, List<Album>> albumsByArtist = albums.collect(groupingBy(album -> 
album.getMainMusician())); 
// グルーピングしたMapから個数を取得 
Map<Artist, Integer> numberOfAlbums = new HashMap<>(); 
for(Entry<Artist, List<Album>> entry : albumsByArtist.entrySet()) { 
numberOfAlbums.put(entry.getKey(), entry.getValue().size()); // => [アーティスト:枚数] 
} 
// アーティスト毎にグルーピング 
public Map<Artist, Long> numberOfAlbums(Stream<Album> albums) { 
return albums.collect(groupingBy(album -> 
album.getMainMusician(), Collectors .counting())); 
} 
counting() を使って同じ処理を簡単に
他の例 
Stream<String> s = Stream.of("a", "bar", "c", "foo"); 
Map<Integer, String> m = s.collect(Collectors.groupingBy(t -> t.length() 
, Collectors.joining())); 
System.out.println(m); // => {1=ac, 3=barfoo} 
こんな感じでgroupingByの第2引数のCollectorを 
「downstream collectors」と呼ぶ 
主に第一引数の結果になにかしらの処理を行いときに使う。 
averagingInt,summarizingLong,もそういった意味では 
「downstream collectors」の一種
今度は個数じゃなく、アルバム名が欲しい場合 
前回同様グルーピングしてから、マッピング 
public Map<Artist, List<String>> nameOfAlbumsDumb(Stream<Album> albums) { 
Map<Artist, List<Album>> albumsByArtist = albums.collect( 
groupingBy(album ->album.getMainMusician())); 
Map<Artist, List<String>> nameOfAlbums = new HashMap<>(); 
for(Entry<Artist, List<Album>> entry : albumsByArtist.entrySet()) { 
nameOfAlbums.put(entry.getKey(), entry.getValue() 
.stream() 
.map(Album::getName) 
.collect(toList())); 
} 
return nameOfAlbums; 
}
「mapping」を使って簡単に 
public Map<Artist, List<String>> nameOfAlbums(Stream<Album> albums) { 
return albums.collect(groupingBy( 
Album::getMainMusician, mapping(Album::getName, toList()))); 
}
Refactoring and Custom Collectors 
リファクタリングと独自Collectors 
java7で書かれた以下のソースを独自のStringjoiningcollectorを使って 
java8のソースへリファクタしていこう。 
※JDK自体は今回作るcollectorを既に提供している。今回はあくまで、勉強の 
ために。 
StringBuilder builder = new StringBuilder("["); 
for (Artist artist : artists) { 
if (builder.length() > 1) { 
builder.append(", "); 
} 
String name = artist.getName(); 
builder.append(name); 
} 
builder.append("]"); 
String result = builder.toString(); 
結果= [aa,bb,cc]といった感じ
第1ステップ 
streamとmapを使った修正してみる 
StringBuilder builder = new StringBuilder("["); 
artists.stream() 
.map(Artist::getName) 
.forEach(name -> { 
if (builder.length() > 1) 
builder.append(", "); 
builder.append(name); 
}); 
builder.append("]"); 
String result = builder.toString(); 
for分の中が大きいし、 
まだまだ読みにくい。
第2ステップ 
reduceを使ってみる 
StringBuilder reduced = artists.stream() 
.map(Artist::getName) 
.reduce(new StringBuilder(), (builder, name) -> { 
if (builder.length() > 0) { 
builder.append(", "); 
} 
builder.append(name); 
return builder; 
}, (left, right) -> left.append(right)); 
reduced.insert(0, "["); 
reduced.append("]"); 
String result = reduced.toString(); 
よけい読みにくく。。
第3ステップ 
独自のStringCombinerクラスを生成 
前回と違って、結合処理は全部このクラスに隠して実装 
StringCombiner combined = artists.stream() 
.map(Artist::getName) 
.reduce(new StringCombiner(", ", "[", "]"), 
StringCombiner::add, 
StringCombiner::merge); 
String result = combined.toString();
第3.1ステップ 
public StringCombiner add(String element) { 
if (areAtStart()) { 
builder.append(prefix); 
} else { 
builder.append(delim); 
} 
builder.append(element); 
return this; 
} 
StringCombiner のaddメソッドの中身
第3.2ステップ 
public StringCombiner merge(StringCombiner other) { 
builder.append(other.builder); 
return this; 
} 
StringCombiner のmergeメソッドの中身
第3.3ステップ 
最後のメソッドチェインになるようにtoStringを追加 
String combined = artists.stream() 
.map(Artist::getName) 
.reduce(new StringCombiner(", ", "[", "]"), 
StringCombiner::add, 
StringCombiner::merge) 
.toString(); 
String result = combined;
第4ステップ 
ただ、これを汎用的に使うのは難しい。 
なので汎用的に使えるようにreduce処理をCollectorにしてしまう。 
今回それをStringCollectorとして新しく作成。 
String result = artists.stream() 
.map(Artist::getName) 
.collect(new StringCollector(", ", "[", "]")); 
これで完全に独自Collectorを作ることができて、シンプルに。 
他のCollectorとまったく同じ形式で使える。
早速StringCollector を実装してみる
その前に。。。
独自Collectorの作り方 
Collectorインターフェイスをimplement 
public interface Collector<T, A, R> { 
~ 
} 
<処理対象の型、実処理の型、返却値の型> 
例えば「Collector<String, ?, Integer>」だと、Stream<String>からIntegerを生成する。
Collectorインターフェイスに定義されている 
4つのメソッドを実装してあげる。 
メソッド名戻り値の型ラムダ式表現内容 
supplier Supplier<A> () -> A 前処理 → 要素の集積に使うオブジェクトを生成する 
accumulator BiConsumer<A,T> (A, T) -> () 
集積 → 集積オブジェクト(A)と、Streamの1要素を引数 
に、集積オブジェクトに要素を集積する 
combiner BinaryOperator<A> (A,A) -> A 結合 → 並列処理の結果2つから1つの結果にまとめる 
finisher Function<A,R> A -> R 後処理 → 集積オブジェクトを最後に変換する
では、実際にStringCollector を実装
1.supplier 
public Supplier<StringCombiner> supplier() { 
return () -> new StringCombiner(delim, prefix, suffix); 
} 
前に作ったStringCombinerを使って 
イメージ的には横の図 
パラレルで動作することもあるのでSupplierは2つ。 
supplierでコンテナオブジェクトを作成している。 
(ここでいうコンテナオブジェクトはStringCombiner)
2.accumulator 
public BiConsumer<StringCombiner, String> accumulator() { 
return StringCombiner::add; 
} 
Supplierと同様に前に作ったStringCombinerを使って 
Streamの値をコンテナオブジェクトに追加している。
3.combine 
public BinaryOperator<StringCombiner> combiner() { 
return StringCombiner::merge; 
} 
同様に前に作ったStringCombinerを使って 
combineで並行で処理していたものを統一。 
この際には新しいContainerに登録している。
4.finsher 
public Function<StringCombiner, String> finisher() { 
return StringCombiner::toString; 
} 
toStringの値を最終的な戻り値として生成 
finsherで最終的な成果物を生成
完成 
public class StringCollector implements Collector<String, StringCombiner, String> { 
public Supplier<StringCombiner> supplier() { 
return () -> new StringCombiner(delim, prefix, suffix); 
} 
public BiConsumer<StringCombiner, String> accumulator() { 
return StringCombiner::add; 
} 
public BinaryOperator<StringCombiner> combiner() { 
return StringCombiner::merge; 
} 
public Function<StringCombiner, String> finisher() { 
return StringCombiner::toString; 
} 
}
Collection Niceties 
1.Mapを使ってキャッシュしていた実装も 
ラムダが導入されたお陰でシンプルに。 
Mapに存在しない場合はDBに問い合わせるキャッシュの例 
public Artist getArtist (String name) { 
Artist artist = artistCache.get(name); 
if (artist == null) { 
artist = readArtistFromDB(name); 
artistCache.put(name, artist); 
} 
return artist; 
} 
public Artist getArtist(String name) { 
return artistCache.computeIfAbsent(name, this::readArtistFromDB); 
} 
computeIfAbsentメソッドで代替可能
2.Mapを使ってのforeach分もシンプルに。 
Map<Artist, Integer> countOfAlbums = new HashMap<>(); 
for(Map.Entry<Artist, List<Album>> entry : albumsByArtist.entrySet()) { 
Artist artist = entry.getKey(); 
List<Album> albums = entry.getValue(); 
countOfAlbums.put(artist, albums.size()); 
} 
Map<Artist, Integer> countOfAlbums = new HashMap<>(); 
albumsByArtist.forEach((artist, albums) -> { 
countOfAlbums.put(artist, albums.size()); 
});
まとめ 
・メソッド参照は簡単な記述でメソッドの参照ができる。 
・Collectorはreduceメソッドの可変なanalogueだし、 
Streamの最終的な値を操作できる。 
・Java8から様々なCollectionを集計でき、独自 
Collectorも作成できるようになった。

Weitere ähnliche Inhalte

Was ist angesagt?

C# LINQ ~深く知って、使いまくろう~
C# LINQ ~深く知って、使いまくろう~C# LINQ ~深く知って、使いまくろう~
C# LINQ ~深く知って、使いまくろう~Fujio Kojima
 
F#とC#で見る関数志向プログラミング
F#とC#で見る関数志向プログラミングF#とC#で見る関数志向プログラミング
F#とC#で見る関数志向プログラミングsatoshimurakumo
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Yuichi Sakuraba
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜勝成 鈴江
 
LINQソースでGO!
LINQソースでGO!LINQソースでGO!
LINQソースでGO!Kouji Matsui
 
Pythonで始めるDropboxAPI
Pythonで始めるDropboxAPIPythonで始めるDropboxAPI
Pythonで始めるDropboxAPIDaisuke Igarashi
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2Tomohiro Namba
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsC#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsFumitaka Yamada
 
Metaprogramming in JuliaLang
Metaprogramming in JuliaLangMetaprogramming in JuliaLang
Metaprogramming in JuliaLangYuichi Motoyama
 
メタプログラミング C#
メタプログラミング C#メタプログラミング C#
メタプログラミング C#Fujio Kojima
 
研究生のためのC++ no.4
研究生のためのC++ no.4研究生のためのC++ no.4
研究生のためのC++ no.4Tomohiro Namba
 

Was ist angesagt? (20)

Applicative functor
Applicative functorApplicative functor
Applicative functor
 
C# LINQ ~深く知って、使いまくろう~
C# LINQ ~深く知って、使いまくろう~C# LINQ ~深く知って、使いまくろう~
C# LINQ ~深く知って、使いまくろう~
 
Junit4
Junit4Junit4
Junit4
 
Sml#探検隊
Sml#探検隊Sml#探検隊
Sml#探検隊
 
CLR/H No.35-2
CLR/H No.35-2CLR/H No.35-2
CLR/H No.35-2
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
Task
TaskTask
Task
 
F#とC#で見る関数志向プログラミング
F#とC#で見る関数志向プログラミングF#とC#で見る関数志向プログラミング
F#とC#で見る関数志向プログラミング
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
 
LINQソースでGO!
LINQソースでGO!LINQソースでGO!
LINQソースでGO!
 
Pythonで始めるDropboxAPI
Pythonで始めるDropboxAPIPythonで始めるDropboxAPI
Pythonで始めるDropboxAPI
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsC#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to Objects
 
Metaprogramming in JuliaLang
Metaprogramming in JuliaLangMetaprogramming in JuliaLang
Metaprogramming in JuliaLang
 
メタプログラミング C#
メタプログラミング C#メタプログラミング C#
メタプログラミング C#
 
研究生のためのC++ no.4
研究生のためのC++ no.4研究生のためのC++ no.4
研究生のためのC++ no.4
 

Ähnlich wie Java8 Lambda chapter5

Java8 lambdas chap03
Java8 lambdas chap03Java8 lambdas chap03
Java8 lambdas chap03ohtsuchi
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルなおき きしだ
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみたAtsushi Kanehara
 
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapSwift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapTomohiro Kumagai
 
Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Appresso Engineering Team
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」Nagi Teramo
 
ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件Kazuki MATSUMOTO
 
Programming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びProgramming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びdekosuke
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編Etsuji Nakai
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方Satoshi Nagayasu
 
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Relations Team
 

Ähnlich wie Java8 Lambda chapter5 (20)

Java8 lambdas chap03
Java8 lambdas chap03Java8 lambdas chap03
Java8 lambdas chap03
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイル
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみた
 
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsapSwift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
Swift 3.0 の新機能 - 追加・変更まわりだけ、ざっくり紹介 2 #devsap
 
Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34Effective java 輪読会 第6章 項目32-34
Effective java 輪読会 第6章 項目32-34
 
Project lambda
Project lambdaProject lambda
Project lambda
 
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
「plyrパッケージで君も前処理スタ☆」改め「plyrパッケージ徹底入門」
 
ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件
 
Programming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選びProgramming Haskell Chapter 11 切符番号選び
Programming Haskell Chapter 11 切符番号選び
 
Swiftおさらい
SwiftおさらいSwiftおさらい
Swiftおさらい
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編
 
Tokyor23 doradora09
Tokyor23 doradora09Tokyor23 doradora09
Tokyor23 doradora09
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方
 
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
 

Java8 Lambda chapter5