Javaを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計 (リスト&ビーン編)
Javaでのリスト&ビーンを使用したアルゴリズムの書き方の覚書です。
説明に使用するデータ構造
アルゴリズムの説明のために、以下のようなビーンのリストを使います。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 国データ */ class Country { private String name; // 名前 private String currency; // 通貨 private Integer population; // 人口 public void setName( String name ) { this.name = name; } public String getName() { return name; } public void setCurrency( String currency ) { this.currency = currency; } public String getCurrency() { return currency; } public void setPopulation( Integer population ) { this.population = population; } public Integer getPopulation() { return population; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// Listcountries = new ArrayList (); Country country; country = new Country(); country.setName( "日本" ); country.setCurrency( "JPY" ); country.setPopulation( 127156000 ); countries.add( country ); country = new Country(); country.setName( "フランス" ); country.setCurrency( "EUR" ); country.setPopulation( 65073482 ); countries.add( country ); country = new Country(); country.setName( "スペイン" ); country.setCurrency( "EUR" ); country.setPopulation( 44904000 ); countries.add( country ); country = new Country(); country.setName( "ロシア" ); country.setCurrency( "RUB" ); country.setPopulation( 141903979 ); countries.add( country ); country = new Country(); country.setName( "ベトナム" ); country.setCurrency( "VND" ); country.setPopulation( 84238000 ); countries.add( country ); country = new Country(); country.setName( "カンボジア" ); country.setCurrency( "KHR" ); country.setPopulation( 14805000 ); countries.add( country ); country = new Country(); country.setName( "コートジボワール" ); country.setCurrency( "XOF" ); country.setPopulation( 44904000 ); countries.add( country );
このマップのリストの内容は、以下のようなコードで表示できます。
////////////////////////////////////////////////////////////////// // 各項目の最大長を求める。 ////////////////////////////////////////////////////////////////// int nameLen = length( "名前" ); int currencyLen = length( "通貨" ); int populationLen = length( "人口" ); for ( int i = 0; i < countries.size(); ++i ) { Country country = countries.get( i ); String name = country.getName(); String currency = country.getCurrency(); String population = country.getPopulation().toString(); if ( length( name ) > nameLen ) { nameLen = length( name ); } if ( length( currency ) > currencyLen ) { currencyLen = length( currency ); } if ( length( population ) > populationLen ) { populationLen = length( population ); } } ////////////////////////////////////////////////////////////////// // データをテーブルの形で出力する。 ////////////////////////////////////////////////////////////////// // 区切り文字列を作成する。 String separator = "+" + padding( "", nameLen, '-' ) + "+" + padding( "", currencyLen, '-' ) + "+" + padding( "", populationLen, '-' ) + "+"; // 区切り文字列を出力する。 System.out.println( separator ); // ヘッダ文字列を出力する。 System.out.println( "|" + padding( "名前", nameLen ) + "|" + padding( "通貨", currencyLen ) + "|" + padding( "人口", populationLen ) + "|" ); // 区切り文字列を出力する。 System.out.println( separator ); // データを出力する。 for ( int i = 0; i < countries.size(); ++i ) { Country country = countries.get( i ); String name = country.getName(); String currency = country.getCurrency(); String population = country.getPopulation().toString(); System.out.println( "|" + padding( name, nameLen ) + "|" + padding( currency, currencyLen ) + "|" + padding( population, populationLen ) + "|" ); } // 区切り文字列を出力する。 System.out.println( separator ); … ////////////////////////////////////////////////////////////////// // 以下、ユーティリティメソッド ////////////////////////////////////////////////////////////////// /* 文字列のバイト数を取得する。 */ private static int length( String str ) { return str.getBytes().length; } /* 文字列を空白でパディングする。 */ private static String padding( String str, int length ) { return padding( str, length, ' ' ); } /* 文字列を指定した文字でパディングする。 */ private static String padding( String str, int length, char padChar ) { int spaceCount = length - str.getBytes().length; StringBuffer buf = new StringBuffer(); for ( int i = 0; i < spaceCount; ++i ) { buf.append( padChar ); } return str + buf.toString(); }
このコードの実行結果は以下の通りです。
+----------------+----+---------+ |名前 |通貨|人口 | +----------------+----+---------+ |日本 |JPY |127156000| |フランス |EUR |65073482 | |スペイン |EUR |44904000 | |ロシア |RUB |141903979| |ベトナム |VND |84238000 | |カンボジア |KHR |14805000 | |コートジボワール|XOF |44904000 | +----------------+----+---------+
■抽出
複数のデータの中から、特定の条件を満たすデータを抽出するアルゴリズムです。
例として、商品データproductsから特定の条件を満たすデータを抽出します。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 商品データ */ class Product { private String product_id; // 商品ID private String product_name; // 商品名 private Integer price; // 価格 public void setProduct_id( String product_id ) { this.product_id = product_id; } public String getProduct_id() { return product_id; } public void setProduct_name( String product_name ) { this.product_name = product_name; } public String getProduct_name() { return product_name; } public void setPrice( Integer price ) { this.price = price; } public Integer getPrice() { return price; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// List
商品データproductsを表示すると、以下のようになります。
+------+----------+----+ |商品ID|商品名 |価格| +------+----------+----+ |1010 |えんぴつ |80 | |1020 |ボールペン|100 | |1030 |消しゴム |100 | |2010 |定規 |140 | |2020 |コンパス |300 | |3010 |のり |200 | +------+----------+----+
以下のコードは、商品データproductsから「price > 100」を満たすデータを抽出します。
// 抽出結果を格納するリスト Listresults = new ArrayList (); // すべての商品データについて繰り返す。 for ( int i = 0; i < products.size(); ++i ) { product = products.get( i ); // 商品データのpriceが100より大きいことを確認する。 Integer price = product.getPrice(); if ( price > 100 ) { // 商品データを抽出結果に追加する。 results.add( product ); } }
抽出結果は、変数resultsに格納されます。抽出結果resultを表示すると、以下のようになります。
+------+--------+----+ |商品ID|商品名 |価格| +------+--------+----+ |2010 |定規 |140 | |2020 |コンパス|300 | |3010 |のり |200 | +------+--------+----+
■ソート
複数のデータを、特定の条件でソートするアルゴリズムです
Javaでのリストのソート
ソートの例の前に、Javaでのリストのソートについて説明します。
リストをソートするには、Collectionsクラスのsort()メソッドを使用します。
Listlist = new ArrayList (); list.add( 13 ); list.add( 43 ); list.add( 22 ); list.add( 234 ); Collections.sort( list, new Comparator () { public int compare( Integer a, Integer b ) { // 引数1と引数2はそれぞれリスト中の値 // compareTo()メソッドにより引数の大小比較を行う。 // ・引数2の方が大きければ、戻り値は正の整数: 引数2→引数1の順に並ぶ。 // ・引数同士が一致すれば、戻り値は0: 引数1と引数2は同列。 // ・引数1の方が大きければ、戻り値は負の整数: 引数1→引数2の順に並ぶ。 return b.compareTo( a ); } } );
ソートの並び順は、sort()メソッドの引数に渡すComparatorの実装クラス中のcompare()メソッドで決めます。
compare()メソッドには引数としてリストの要素が2つずつ渡されます。引数2→引数1の順に並べたい場合は正の値を、引数1と引数2を同列にしたい場合は0を、引数1→引数2の順に並べたい場合は負の値を、compare()メソッドの戻り値として返します。
なお、上記のコードはリストの要素を「数値の降順」にソートします。
ソートの例(五十音順)
それでは、ソートの例を挙げます。
例として、売上データsalesを特定の項目の「五十音順」にソートします。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 売上データ */ class Sale { private String sales_date; // 売上日 private String sales_no; // 売上番号 private String product_id; // 商品ID private Integer amount; // 数量 public void setSales_date( String sales_date ) { this.sales_date = sales_date; } public String getSales_date() { return sales_date; } public void setSales_no( String sales_no ) { this.sales_no = sales_no; } public String getSales_no() { return sales_no; } public void setProduct_id( String product_id ) { this.product_id = product_id; } public String getProduct_id() { return product_id; } public void setAmount( Integer amount ) { this.amount = amount; } public Integer getAmount() { return amount; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// Listsales = new ArrayList (); Sale sale; sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00001" ); sale.setProduct_id( "1020" ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00002" ); sale.setProduct_id( "1010" ); sale.setAmount( 5 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00003" ); sale.setProduct_id( "3010" ); sale.setAmount( 20 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00001" ); sale.setProduct_id( "1030" ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00002" ); sale.setProduct_id( "1020" ); sale.setAmount( 15 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00001" ); sale.setProduct_id( "2020" ); sale.setAmount( 30 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00002" ); sale.setProduct_id( "3010" ); sale.setAmount( 20 ); sales.add( sale );
売上データsalesを表示すると、以下のようになります。
+--------+--------+------+----+ |売上日 |売上番号|商品ID|数量| +--------+--------+------+----+ |20090702|00001 |1020 |10 | |20090702|00002 |1010 |5 | |20090702|00003 |3010 |20 | |20090703|00001 |1030 |10 | |20090703|00002 |1020 |15 | |20090704|00001 |2020 |30 | |20090704|00002 |3010 |20 | +--------+--------+------+----+
以下のコードは、売上データsalesを「五十音順でsales_noの昇順」にソートします。
Collections.sort( sales, new Comparator() { public int compare( Sale sale1, Sale sale2 ) { // 引数1と引数2はそれぞれ売上データ。 // 売上データからsales_noを取得する。 String sales_no1 = sale1.getSales_no(); String sales_no2 = sale2.getSales_no(); //////////////////////////////////////////// // sales_noを比較する。 //////////////////////////////////////////// // compareToによりproduct_idの大小を比較する。 // ・引数2のproduct_idの方が大きければ、戻り値は正の整数: 引数2→引数1の順に並ぶ。 // ・product_idが一致すれば、戻り値は0: 引数1と引数2の同列。 // ・引数1のproduct_idの方が大きければ、戻り値は負の整数: 引数1→引数2の順に並ぶ。 return sales_no1.compareTo( sales_no2 ); } } );
ソート後の売上データsalesを表示すると、以下のようになります。
+--------+--------+------+----+ |売上日 |売上番号|商品ID|数量| +--------+--------+------+----+ |20090702|00001 |1020 |10 | |20090703|00001 |1030 |10 | |20090704|00001 |2020 |30 | |20090702|00002 |1010 |5 | |20090703|00002 |1020 |15 | |20090704|00002 |3010 |20 | |20090702|00003 |3010 |20 | +--------+--------+------+----+
ソートの例(数値順)
例をもう一つ挙げます。商品データproductsを特定の項目の「数値順」にソートします。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 商品データ */ class Product { private String product_id; // 商品ID private String product_name; // 商品名 private Integer price; // 価格 public void setProduct_id( String product_id ) { this.product_id = product_id; } public String getProduct_id() { return product_id; } public void setProduct_name( String product_name ) { this.product_name = product_name; } public String getProduct_name() { return product_name; } public void setPrice( Integer price ) { this.price = price; } public Integer getPrice() { return price; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// Listproducts = new ArrayList (); Product product; product = new Product(); product.setProduct_id( "2010" ); product.setProduct_name( "定規" ); product.setPrice( 140 ); products.add( product ); product = new Product(); product.setProduct_id( "2020" ); product.setProduct_name( "コンパス" ); product.setPrice( 300 ); products.add( product ); product = new Product(); product.setProduct_id( "3010" ); product.setProduct_name( "のり" ); product.setPrice( 200 ); products.add( product ); product = new Product(); product.setProduct_id( "1030" ); product.setProduct_name( "消しゴム" ); product.setPrice( 100 ); products.add( product ); product = new Product(); product.setProduct_id( "1020" ); product.setProduct_name( "ボールペン" ); product.setPrice( 100 ); products.add( product ); product = new Product(); product.setProduct_id( "1010" ); product.setProduct_name( "えんぴつ" ); product.setPrice( 80 ); products.add( product );
商品データproductsを表示すると、以下のようになります。
+------+----------+----+ |商品ID|商品名 |価格| +------+----------+----+ |2010 |定規 |140 | |2020 |コンパス |300 | |3010 |のり |200 | |1030 |消しゴム |100 | |1020 |ボールペン|100 | |1010 |えんぴつ |80 | +------+----------+----+
以下のコードは、商品データproductsを「数値順でproduct_idの降順」にソートします。
Collections.sort( products, new Comparator() { public int compare( Product product1, Product product2 ) { // 引数1と引数2はそれぞれ商品データ。 // 商品データのproduct_idを取得する。 String product_id1 = product1.getProduct_id(); String product_id2 = product2.getProduct_id(); //////////////////////////////////////////// // product_idを比較する。 //////////////////////////////////////////// // compareTo()メソッドによりproduct_idの大小を比較する。 // ・引数2のproduct_idの方が大きければ、戻り値は正の整数: 引数2→引数1の順に並ぶ。 // ・product_idが一致すれば、戻り値は0: 引数1と引数2の同列。 // ・引数1のproduct_idの方が大きければ、戻り値は負の整数: 引数1→引数2の順に並ぶ。 return product_id2.compareTo( product_id1 ); } } );
ソート後の商品データproductsを表示すると、以下のようになります。
+------+----------+----+ |商品ID|商品名 |価格| +------+----------+----+ |3010 |のり |200 | |2020 |コンパス |300 | |2010 |定規 |140 | |1030 |消しゴム |100 | |1020 |ボールペン|100 | |1010 |えんぴつ |80 | +------+----------+----+
■結合
2種類のデータを、特定の条件で結合するアルゴリズムです。
例として、商品データproductsと売上データsalesを結合します。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 商品データ */ class Product { private String product_id; // 商品ID private String product_name; // 商品名 private Integer price; // 価格 public void setProduct_id( String product_id ) { this.product_id = product_id; } public String getProduct_id() { return product_id; } public void setProduct_name( String product_name ) { this.product_name = product_name; } public String getProduct_name() { return product_name; } public void setPrice( Integer price ) { this.price = price; } public Integer getPrice() { return price; } } /** * 売上データ */ class Sale { private String sales_date; // 売上日 private String sales_no; // 売上番号 private String product_id; // 商品ID private String product_name; // 商品名 private Integer amount; // 数量 private Integer price; // 価格 public void setSales_date( String sales_date ) { this.sales_date = sales_date; } public String getSales_date() { return sales_date; } public void setSales_no( String sales_no ) { this.sales_no = sales_no; } public String getSales_no() { return sales_no; } public void setProduct_id( String product_id ) { this.product_id = product_id; } public String getProduct_id() { return product_id; } public void setProduct_name( String product_name ) { this.product_name = product_name; } public String getProduct_name() { return product_name; } public void setAmount( Integer amount ) { this.amount = amount; } public Integer getAmount() { return amount; } public void setPrice( Integer price ) { this.price = price; } public Integer getPrice() { return price; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// Listproducts = new ArrayList (); Product product; product = new Product(); product.setProduct_id( "1010" ); product.setProduct_name( "えんぴつ" ); product.setPrice( 80 ); products.add( product ); product = new Product(); product.setProduct_id( "1020" ); product.setProduct_name( "ボールペン" ); product.setPrice( 100 ); products.add( product ); product = new Product(); product.setProduct_id( "1030" ); product.setProduct_name( "消しゴム" ); product.setPrice( 100 ); products.add( product ); product = new Product(); product.setProduct_id( "2010" ); product.setProduct_name( "定規" ); product.setPrice( 140 ); products.add( product ); product = new Product(); product.setProduct_id( "2020" ); product.setProduct_name( "コンパス" ); product.setPrice( 300 ); products.add( product ); product = new Product(); product.setProduct_id( "3010" ); product.setProduct_name( "のり" ); product.setPrice( 200 ); products.add( product ); List sales = new ArrayList (); Sale sale; sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00001" ); sale.setProduct_id( "1020" ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00002" ); sale.setProduct_id( "1010" ); sale.setAmount( 5 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00003" ); sale.setProduct_id( "3010" ); sale.setAmount( 20 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00001" ); sale.setProduct_id( "1030" ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00002" ); sale.setProduct_id( "1020" ); sale.setAmount( 15 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00001" ); sale.setProduct_id( "2020" ); sale.setAmount( 30 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00002" ); sale.setProduct_id( "3010" ); sale.setAmount( 20 ); sales.add( sale );
商品データproductsを表示すると以下のようになります。
+------+----------+----+ |商品ID|商品名 |価格| +------+----------+----+ |1010 |えんぴつ |80 | |1020 |ボールペン|100 | |1030 |消しゴム |100 | |2010 |定規 |140 | |2020 |コンパス |300 | |3010 |のり |200 | +------+----------+----+
また、売上データsalesを表示すると以下のようになります。
+--------+--------+------+----+ |売上日 |売上番号|商品ID|数量| +--------+--------+------+----+ |20090702|00001 |1020 |10 | |20090702|00002 |1010 |5 | |20090702|00003 |3010 |20 | |20090703|00001 |1030 |10 | |20090703|00002 |1020 |15 | |20090704|00001 |2020 |30 | |20090704|00002 |3010 |20 | +--------+--------+------+----+
以下のコードは、商品データと売上データをproduct_idをキーとして結合します。
///////////////////////////////////////////////////////////////////////////////// // ハッシュテーブルを作成し、 product_idをキーとして商品データを取得できるようにする。 ///////////////////////////////////////////////////////////////////////////////// // ハッシュテーブル MaphashTable = new HashMap (); // すべての商品データについて繰り返す。 for ( int i = 0; i < products.size(); ++i ) { product = products.get( i ); // 商品データのproduct_idを取得する。 String key = product.getProduct_id(); // product_idをキーとして、商品データをハッシュテーブルに格納する。 hashTable.put( key, product ); } ///////////////////////////////////////////////////////////////////////////////// // 売上データと商品データを結合する。 ///////////////////////////////////////////////////////////////////////////////// // すべての売上データについて繰り返す。 for ( int i = 0; i < sales.size(); ++i ) { sale = sales.get( i ); // 売上データのproduct_idを取得する。 String product_id = sale.getProduct_id(); // product_idをキーとして、商品データをハッシュテーブルから取得する。 product = hashTable.get( product_id ); if ( product != null ) { // 商品データを取得できた場合: // 商品データの値を売上データに格納する。 sale.setProduct_name( product.getProduct_name() ); sale.setPrice( product.getPrice() ); } }
結合後の売上データsalsesを表示すると、以下のようになります。
+--------+--------+------+----------+----+----+ |売上日 |売上番号|商品ID|商品名 |数量|価格| +--------+--------+------+----------+----+----+ |20090702|00001 |1020 |ボールペン|10 |100 | |20090702|00002 |1010 |えんぴつ |5 |80 | |20090702|00003 |3010 |のり |20 |200 | |20090703|00001 |1030 |消しゴム |10 |100 | |20090703|00002 |1020 |ボールペン|15 |100 | |20090704|00001 |2020 |コンパス |30 |300 | |20090704|00002 |3010 |のり |20 |200 | +--------+--------+------+----------+----+----+
■集計
複数のデータを特定の条件で集計するアルゴリズムです。
例として、売上データsalesを集計します。
////////////////////////////////////////////////////////////////// // ビーン ////////////////////////////////////////////////////////////////// /** * 売上データ */ class Sale { private String sales_date; // 売上日 private String sales_no; // 売上番号 private String product_name; // 商品名 private Integer price; // 価格 private Integer amount; // 数量 public void setSales_date( String sales_date ) { this.sales_date = sales_date; } public String getSales_date() { return sales_date; } public void setSales_no( String sales_no ) { this.sales_no = sales_no; } public String getSales_no() { return sales_no; } public void setProduct_name( String product_name ) { this.product_name = product_name; } public String getProduct_name() { return product_name; } public void setPrice( Integer price ) { this.price = price; } public Integer getPrice() { return price; } public void setAmount( Integer amount ) { this.amount = amount; } public Integer getAmount() { return amount; } } /** * 集計結果 */ class Result { private String sales_date; // 売上日 private Integer amount; // 合計数量 private Integer total; // 合計売上高 public void setSales_date( String sales_date ) { this.sales_date = sales_date; } public String getSales_date() { return sales_date; } public void setAmount( Integer amount ) { this.amount = amount; } public Integer getAmount() { return amount; } public void setTotal( Integer total ) { this.total = total; } public Integer getTotal() { return total; } } ////////////////////////////////////////////////////////////////// // ビーンのリストの作成 ////////////////////////////////////////////////////////////////// Listsales = new ArrayList (); Sale sale; sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00001" ); sale.setProduct_name( "ボールペン" ); sale.setPrice( 100 ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00002" ); sale.setProduct_name( "えんぴつ" ); sale.setPrice( 80 ); sale.setAmount( 5 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090702" ); sale.setSales_no( "00003" ); sale.setProduct_name( "のり" ); sale.setPrice( 200 ); sale.setAmount( 20 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00001" ); sale.setProduct_name( "消しゴム" ); sale.setPrice( 100 ); sale.setAmount( 10 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090703" ); sale.setSales_no( "00002" ); sale.setProduct_name( "ボールペン" ); sale.setPrice( 100 ); sale.setAmount( 15 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00001" ); sale.setProduct_name( "コンパス" ); sale.setPrice( 300 ); sale.setAmount( 30 ); sales.add( sale ); sale = new Sale(); sale.setSales_date( "20090704" ); sale.setSales_no( "00002" ); sale.setProduct_name( "のり" ); sale.setPrice( 200 ); sale.setAmount( 20 ); sales.add( sale );
売上データsalesを表示すると以下のようになります。
+--------+--------+----------+----+----+ |売上日 |売上番号|商品名 |価格|数量| +--------+--------+----------+----+----+ |20090702|00001 |ボールペン|100 |10 | |20090702|00002 |えんぴつ |80 |5 | |20090702|00003 |のり |200 |20 | |20090703|00001 |消しゴム |100 |10 | |20090703|00002 |ボールペン|100 |15 | |20090704|00001 |コンパス |300 |30 | |20090704|00002 |のり |200 |20 | +--------+--------+----------+----+----+
以下のコードは、salesを集計してsales_date毎の合計数量と合計売上高を求めます。
/////////////////////////////////////////////////////// // 集計結果の初期化 /////////////////////////////////////////////////////// // 集計結果を一時的に格納するマップ MapresultsMap = new HashMap (); // すべての売上データについて繰り返す。 for ( int i = 0; i < sales.size(); ++i ) { sale = sales.get( i ); // 売上データのsales_dateを取得する。 String sales_date = sale.getSales_date(); if ( ! resultsMap.containsKey( sales_date ) ) { // マップにキーsales_dateが含まれていない: // 集計結果の初期値を生成する。 Result result = new Result(); result.setSales_date( sales_date ); result.setAmount( 0 ); result.setTotal( 0 ); // 生成した初期値をキーsales_dateに関連付けてマップに格納する。 resultsMap.put( sales_date, result ); } } /////////////////////////////////////////////////////// // salesを集計 /////////////////////////////////////////////////////// // すべての売上データについて繰り返す。 for ( int i = 0; i < sales.size(); ++i ) { sale = sales.get( i ); // 売上データのsales_dateを取得する。 String sales_date = sale.getSales_date(); // キーsales_dateに関連付く集計結果をオブジェクトから取得する。 Result result = resultsMap.get( sales_date ); // 売上データのamountを集計結果に足し合わせる。 Integer s_amount = sale.getAmount(); Integer r_amount = result.getAmount(); result.setAmount( r_amount + s_amount ); // 売上データのpriceとamountとを掛けた値を集計結果に足し合わせる。 Integer s_price = sale.getPrice(); Integer r_total = result.getTotal(); result.setTotal( r_total + s_price * s_amount ); } /////////////////////////////////////////////////////// // 集計結果をリストに移し替え /////////////////////////////////////////////////////// List results = new ArrayList (); // 一時マップの全てのキーとデータについて繰り返す。 for ( String sales_date : resultsMap.keySet() ) { Result result = resultsMap.get( sales_date ); // データをリストに追加する results.add( result ); } /////////////////////////////////////////////////////// // 集計結果をsales_dateの昇順にソート /////////////////////////////////////////////////////// Collections.sort( results, new Comparator () { public int compare( Result result1, Result result2 ) { String sales_date1 = result1.getSales_date(); String sales_date2 = result2.getSales_date(); return sales_date1.compareTo( sales_date2 ); } } );
集計結果は変数resultsに格納されます。集計結果resultsを表示すると以下のようになります。
+--------+--------+----------+ |売上日 |合計数量|合計売上高| +--------+--------+----------+ |20090702|35 |5400 | |20090703|25 |2500 | |20090704|50 |13000 | +--------+--------+----------+
データ構造
アルゴリズム
- Javaを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計 (リスト&マップ編)
- Javaを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計 (リスト&ビーン編)
- PHPを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計
- VBAを使うなら理解しておきたいアルゴリズム - 抽出・結合・集計
- Javascriptを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計
- SQLを使うなら理解しておきたいアルゴリズム?(というか、select文の書き方) - where・order by・join・group by
- Bashを使うなら理解しておきたいアルゴリズム - 抽出・ソート・結合・集計