Sort-of-List-Map(A)

Similar documents
情報処理Ⅰ

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

JavaプログラミングⅠ

Microsoft PowerPoint - prog03.ppt

プログラミング実習I

Microsoft PowerPoint - prog04.ppt

Microsoft PowerPoint - prog09.ppt

Microsoft PowerPoint - prog09.ppt

Prog1_15th

JavaプログラミングⅠ

Prog1_3rd

JAVA とテンプレート

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

プログラミング基礎I(再)

Prog1_10th

メソッドのまとめ

文字列操作と正規表現

プログラミング入門1

JAVA入門

PowerPoint プレゼンテーション

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

プログラミング入門1

JAVA入門

Java言語 第1回

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

kantan_C_1_iro3.indd

Microsoft PowerPoint - 09.pptx

PowerPoint プレゼンテーション

メディプロ1 Javaプログラミング補足資料.ppt

微分方程式 モデリングとシミュレーション

Javaの作成の前に

JAVA入門

Prog2_9th

メソッドのまとめ

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

デジタル表現論・第4回

(Microsoft PowerPoint - \223\306\217KJAVA\221\346\202R\224\ ppt)

PowerPoint プレゼンテーション

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

プログラミング入門1

Javaプログラムの実行手順

PowerPoint プレゼンテーション

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

Prog1_6th

第1章 ビジュアルプログラミング入門

解答上の注意 1 解答は 解答 紙の問題番号に対応した解答欄にマークしなさい 2 選択肢は 問ごとに 意されています 問 1の選択肢は 問 2で使 しません 3 選択肢は量が多いため 探しやすさの観点よりグループ分けされています グループ分けに合わせて解答欄が区切られていますが 横 1 列で問題 1

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

Microsoft PowerPoint - chap10_OOP.ppt

Method(C 言語では関数と呼ぶ ) メソッドを使うと 処理を纏めて管理することができる 処理 ( メソッド ) の再実行 ( 再利用 ) が簡単にできる y 元々はC 言語の関数であり 入力値に対する値を 定義するもの 数学では F(x) = 2x + 1 など F(x)=2x+1 入力値 (

2

JavaプログラミングⅠ

論理と計算(2)

デジタル表現論・第6回

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

PowerPoint プレゼンテーション

GEC-Java

Java講座

Microsoft PowerPoint - lec06 [互換モード]

PowerPoint プレゼンテーション

ガイダンス

JavaプログラミングⅠ

PowerPoint プレゼンテーション

11 ソフトウェア工学 Software Engineering デザインパターン DESIGN PATTERNS デザインパターンとは? デザインパターン 過去のソフトウェア設計者が生み出したオブジェクト指向設計に関して, ノウハウを蓄積し 名前をつけ 再利用しやすいようにカタログ化したもの 各デ

プログラミング入門1

Functional Programming

オブジェクト指向プログラミング・同演習 5月21日演習課題

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

第8回 関数

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

Microsoft PowerPoint ppt

2. データ構造ヒープに保存するデータは 番号付けられて保存される 従って リスト L として保存することとする 3. アルゴリズム 3.1. 要素の追加新しい要素の追加は リストの終端に置くことで開始する つまり 最下層の一番右 または新たに最下層を生成してその一番左となる この後 この要素を正し

Prog2_10th

Microsoft PowerPoint - Pro110111

PowerPoint プレゼンテーション

JavaプログラミングⅠ

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

ガイダンス

Make the Future Java FY13 PPT Template

1. はじめに 二分木ヒープ 様々なアルゴリズムにおいて ある要素の集合またはリストから 最小 な要素を取り 出す必要がある そのような場合に使われる標準的データ構造が二分木ヒープ (binary heap) である あるオブジェクトO を考える そのオブジェクトは ラベル O. label と値

基本情報STEP UP演習Java対策

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

スライド 1

プログラミング入門1

ガイダンス

Microsoft PowerPoint - prog08.ppt

<4D F736F F D2091E F196E291E889F090E C4816A82CC838C E646F6378>

PowerPoint Presentation

Javaによるアルゴリズムとデータ構造

人工知能入門

slide5.pptx

コンピュータ中級B ~Javaプログラミング~ 第3回 コンピュータと情報をやりとりするには?

2004/11/23 オブジェクト指向プログラミング - モデル図とシーケンス図の表現方法 - オブジェクト指向プログラミング (OOP:ObjectOrientedPrograming) オブジェクト指向プログラミング言語 (OOPL) Java,C++,Delphi(Pascal),Visual

情報実習Ⅱ

memo

スライド 1

開発・運用時のガイド JDK8への移行に伴う留意点 [UNIX]

情報処理Ⅰ演習

memo

Transcription:

Java オブジェクト集合のソートとラムダ式の初歩 山本富士男 2016-4-23 この資料は Java での コレクション Coections と ジェネリクス Generics に関してさらに深く学ぶためのものです 以下の事項を学びます レポート課題が 5 ページの末尾にあります 名称のない内部クラスである 匿名クラス を使う 一般のオブジェクトの集合 (List や Map など ) を何らかの基準でソートする Java SE8 で新たに導入されたラムダ式 (Lambda Expression) を知る ( ラムダ式は ストリーム機能と連携して マルチコア CPU 時代の並列プログラミングに結びつく ) 1. オブジェクトのリストをソートする ( 従来方式で書く ) 簡単な例として K 大学の 5 つの学部名を (String オブジェクトとして )List に登録し その文字数の昇順に並べる 従来の Java で記述したプログラムリストを以下に示す (ListSort_Cassic.java) // import java.uti.*; pubic cass ListSort_Cassic{ pubic static void main(string... args){ List<String> ist = Arrays.asList("E: ", "C: ", "I: ","A: ","N: " ); //Comparator<T> cass MyComparator impements Comparator<String>{ pubic int compare(string o1, String o2) { return o1.ength() - o2.ength(); MyComparator mycpr = new MyComparator(); Coections.sort(ist, mycpr); System.out.printn(" "); for(string s : ist) System.out.printn(s); 実行結果は以下のようになる 学部名を文字数の昇順に列挙します : E: 工学部 I: 情報学部 N: 看護学部 C: 創造工学部 A: 応用バイオ科学部 Arrays.asList で 5 つの String オブジェクト ( 学部名 ) を List にしている この List オブジェクトの型は List<String> になっていることに注意してほしい この List には String 型

オブジェクトを格納するということを意味する (a) Comparator インタフェースの利用 上記プログラムでは List にある String オブジェクトをどのような基準でソートするのかを指定するために Comparator というインタフェースを使っている 正確には Comparator<T> というインタフェースである すなわち 型 T のオブジェクトを比較するためのものである この例では 型 T は String 型なので Comparator<String> を使う インタフェースは クラスではないので 上記では MyComparator という内部クラスを作っている このクラスは Comparator<String> を実装 (impements) している 実装するということは Comparator で宣言されているメソッドの処理内容を この MyComparator クラスで定義するということである この場合 実装すべきメソッドは一つだけであり それは compare メソッドである この compare メソッドの前に というのが付いているのは インタフェース Comparator で宣言されているメソッドの内容をここで定義する と言う意味である Compare メソッドは 引数としてオブジェクトを 2 つ取り それらを並べるための比較 すなわち < = > を判定する方法を与える この例では以下のようになっている //Comparator<T> cass MyComparator impements Comparator<String>{ pubic int compare(string o1, String o2) { return o1.ength() - o2.ength(); compare メソッドの返値 ( 負 ゼロ 正 ) によって 以下のような比較結果になる この例では 負か ゼロか 正かは 文字列の長さの比較で決まることに注意して下さい 負ならば o1 < o2 0 ならば o1 = o2 正ならば o1 > o2 (b) オブジェクトの集合をソートする上記の MyComparator オブジェクト mycpr を用いて List にあるオブジェクトをソートします 具体的には 下記のとおり Coections.sort メソッドの第 2 引数に mycpr を与えます すると 第 1 引数の List オブジェクトに含まれる学部名を mycpr の判定方法によってソートしてくれます MyComparator mycpr = new MyComparator(); Coections.sort(ist, mycpr);

2. オブジェクトのリストをソートする ( 匿名クラスを使う ) 上では Comparator インタフェースを実装するクラス MyComparator を定義し そのオブジェクトを生成して sort メソッドに渡していました この MyComparator というクラスは そのオブジェクトを sort へ渡すためだけに定義されたものです 実は そのような場合は 特に 明示的に MyComparator のようなクラスを作らずに そのオブジェクトを直接 sort メソッドへ渡してしまうのが通例です それが 匿名クラス のオブジェクトを生成して利用するということです すなわち 以下のようなソースリストになります 実際 Coections.sort の第 2 引数は インターフェース Comparator のメッソド compare を実装したクラスのオブジェクトを生成する という形になっています compare メソッドの定義内容が そっくりそのまま この第 2 引数の内部に入っています (ListSort_Anony.java) // import java.uti.*; pubic cass ListSort_Anony{ pubic static void main(string... args){ List<String> ist = Arrays.asList("E: ", "C: ", "I: ","A: ","N: " ); //Comparator<T> Coections.sort(ist, new Comparator<String>() { pubic int compare(string o1, String o2) { return o1.ength() - o2.ength(); ); System.out.printn(" "); for(string s : ist) System.out.printn(s); 上記の考え方は 余分なクラスを定義しないので 良い方向のように思えます 実際 この方法は多用されています しかし 上記のとおり sort メソッドの第 2 引数が 肥大化 して やや読み難い感は免れません さらにこのようなメソッドの個数や 引数の個数が増えた場合は かなり長い 理解しにくいソースプログラムリストになってしまうことでしょう Java の開発者は そのような悪い事態を避けて さらに近年の PC のマルチコアの性能を引き出すための言語仕様の改訂検討を続けていました それに10 年を要したと言われています そして それが Java SE8 として結実し 世の中へ出ました そのうちで 最も重要なものがラムダ式 (Lambda Expression) と呼ばれるものです 次の節では ここで取り上げたオブジェクトの sort が ラムダ式によって如何に簡潔 明瞭に書けるよ うになったかを示します

3. オブジェクトのリストをソートする ( ラムダ式を使う ) 結論を先に示します 上記と同じ例題を ラムダ式を用いて書いたソースリストを以下に示します (ListSort_Lambda.java) // import java.uti.*; pubic cass ListSort_Lambda{ pubic static void main(string... args){ List<String> ist = Arrays.asList("E: ", "C: ", "I: ","A: ","N: " ); //Java SE8 Lambda Expression Coections.sort(ist, (s1, s2)-> s1.ength() - s2.ength()); System.out.printn(" "); ist.foreach(s -> System.out.printn(s)); // ソートを行う Coections.sort の呼び出し状況を 先の 匿名クラスを使う 場合と 今回の ラムダ式を使う 場合をあらためて比較してみます : ( 匿名クラスを使う場合 ) Coections.sort(ist, new Comparator<String>() { pubic int compare(string o1, String o2) { return o1.ength() - o2.ength(); ); ( ラムダ式を使う場合 ) Coections.sort(ist, (s1, s2)-> s1.ength() - s2.ength()); 行数だけ比較しても 6 行がわずか 1 行になってしまいました! 驚異的です この後説明しますが これだけ簡潔に書けることは 処理内容が明確に理解でき 間違いも起こりにくく ソフトウェアの生産性に大きく寄与すると考えられます そのため 注目度が高いのだと思われます Coections.sort の第 2 引数を再度見ます 匿名クラス では new 演算子で明らかにオブジェクトを生成して与えています それに対して ラムダ式 の方は オブジェクトを生成しているようには見えません! 単に 関数のような式を与えています そのとおりです ラムダ式を使うことで オブジェクトをあたかも関数のように扱える のです この例でのラムダ式は 以下のような関数の形になっています ( 引数 1, 引数 2, ) -> 計算式 ( 処理手順のステートメント ) (s1, s2)-> s1.ength() - s2.ength() もしも 学部名の文字数ではなく 辞書順 ( 学部名の先頭が英字になっています ) にソート

するにはどうすればよいでしょうか? 答えは ラムダ式を以下のように変えるだけです String クラスの compareto メソッドを利用しています (s1, s2)-> s1.compareto(s2) 実行結果は以下のようになります A: 応用バイオ科学部 C: 創造工学部 E: 工学部 I: 情報学部 N: 看護学部 4. ラムダ式でなぜこんなに簡単に書けるのか 上記の例だけでも ラムダ式の威力が感じられます しかし なぜ こんなに簡潔に書けることになったのでしょうか それを簡単に説明します (1) 関数型インタフェース上記の Comparator<T> というインタフェースでは それを impements するクラスが実装すべきメソッドは唯一つしかありません そして この例では T 型は String 型でした 以下のメソッドでした このように 実装すべきメソッドを唯一つしか持たないインタフェースは 関数型インタフェースと呼ばれます 実装すべき唯一つのメソッド pubic int compare(string o1, String o2) (2) 関数型インタフェースからラムダ式へ関数型インタフェースならば 実装すべき関数名 ( メソッド名 ) 引数の型と個数は決まっていますから それらを明示的に書かなくても使えることになります したがって 以下のように ラムダ式では 実装すべき関数 ( メソッド ) の処理内容だけが分かるように書いても良いことになったのです 以下のとおりです ( 先の例を再掲します ) (s1, s2)-> s1.ength() - s2.ength() この場合の Coections.sort では 関数型インタフェース Comparator<String> なので 比較するオブジェクトは String 型である だから ラムダ式の s1, s2 という引数は String オブジェクトであることは分かっている ソートの基準は それらの String の長さ ength() の差で決める ということだけを指示すればよいのです 課題 ( レポート提出が必要です ) 学部名称の長さの昇順ではなく 降順にソートするにはどうしたらよいでしょうか? ラムダ式を使ったソースリストと実行結果を提出しなさい ( 実行結果は以下のようになるはず ) A: 応用バイオ科学部 C: 創造工学部 I: 情報学部 N: 看護学部 E: 工学部

5. 内部イテレータにも発想の転換 ラムダ式関係で もうひとつ重要なことがあります List の要素 (String オブジェクト ) を列挙して出力する場合に 上記に示した 従来方式の記述 と ラムダ式を使う場合 で大きな違いがあります 具体的にみてみます ( 従来型の記述 ) 外部イテレータ for(string s : ist) System.out.printn(s); ( ラムダ式を使う場合 ) 内部イテレータ ist.foreach(s -> System.out.printn(s)); 両者の違いは何でしょうか? まるで 主役が for ループから ist そのものへ入れ替わった雰囲気です 外部イテレータの場合 : どのように反復するのかという制御を主題として for ループで書いている List の要素を一つ取り出し それをプリントする これを繰り返す 反復制御処理と処理自体が連動 混在している 処理の内部で 外側の for 文のローカル変数へアクセスしている!( これは並列処理を考える上で重大な事項なのだ!) 要素に対して どのように howto 処理したいのかという観点で書いている 内部イテレータの場合 : 要素に対する処理自体は ラムダ式で書かれ 反復制御から分離されている 要素に対して 何を what したいのかという観点で書いている