質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

7414閲覧

完成例を実現する方法を教えてください。

lena

総合スコア31

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/03/27 16:35

JAVA初心者です。
下記のような商品別売上げデータ表を作成していますが商品マスタと売上明細の結合が上手くいきません。

【仕様内容】
商品マスタのデータと売上明細の商品コードを比較し一致したら、
出力ファイルに売上明細と商品マスタにある必要なデータを抽出し出力する。
売上明細をもとに商品マスタより商品名と単価を取得します。
売上明細を出力した後、売上金額の大きい商品の順に出力します(sort機能は使用しない)。

【問題点】
①商品マスタと売上明細の結合方法が分からない。
②//売上データのamtを集計結果に加算するというところで、
下記のエラーが表示される。
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.lang.Integer
③売上金額を昇順に並べ替える方法が分からない。
④売上金額順に出力したいがどのデータを抽出してよいのか分からない。

どのようにすれば完成例を実現することができるのでしょうか。
どうぞよろしくお願いいたします。

【完成例】 商品名,数量,売上金額 シャーペン,5,500 セロテープ,4,800 ノート,7,840 消しゴム,6,600 付箋,3,450 シャーペン,2,200 定規,4,560 付箋,2,300 商品マスタ未存在,, 商品名,合計数量,合計売上高 ノート,7,840 セロテープ,4,800 付箋,5,750 シャーペン,7,700 消しゴム,6,600 定規,4,560
package lessons; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class DataProcessing { public static void main(String[] args) { BufferedReader brP = null; BufferedReader brS = null; BufferedWriter bwO = null; List<Map<String, Object>> products = new ArrayList<Map<String, Object>>(); Map<String, Object> product = null; List<Map<String, Object>> sales = new ArrayList<Map<String, Object>>(); Map<String, Object> sale = null; String stP = ""; //inPファイルデータを格納 String stS = ""; //inSファイルデータを格納 String[] itemP = null ; //inPファイルデータを配列に格納 String[] itemS = null ; //inSファイルデータを配列に格納 Map<Object, Map<String, Object>> hashTable = new HashMap<Object, Map<String, Object>>(); Map<Object, Map<String, Object>> resultsMap = new HashMap<Object, Map<String, Object>>(); Map<String, Object> result = null; final String noItem = "商品マスタ未存在"; try{ try{ brP = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Users/temp/Desktop/inP.csv"),"JISAutoDetect")); }catch(FileNotFoundException e){ System.err.println("inM.csvファイルが見つかりません。"); } try{ brS = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Users/temp/Desktop/inS.csv"),"JISAutoDetect")); }catch(FileNotFoundException e){ System.err.println("inA.csvファイルが見つかりません。"); } try{ bwO = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:/Users/temp/Desktop/outO.csv"),"SJIS")); }catch(FileNotFoundException e){ System.err.println("outA.csvファイルが見つかりません。"); } while((stP = brP.readLine()) != null){ if(stP.equals("")){ System.err.println("データに不備があります。"); } itemP = stP.split(","); product = new HashMap<String, Object>(); product.put("code",itemP[0]); //商品コード product.put("name",itemP[1]); //商品名 product.put("price",itemP[2]); //単価 products.add(product); } for ( int i = 0; i < products.size(); ++i ) { product = products.get( i ); // 商品データのcodeを取得する。 Object key = product.get( "code" ); // codeをキーとして、商品データをハッシュテーブルに格納する。 hashTable.put( key, product ); //System.out.println(hashTable); } bwO.write("商品名" + "," + "数量" + " ," + "売上金額"); bwO.newLine(); try{ while((stS = brS.readLine()) != null){ if(stS.equals("")){ System.err.println("データに不備があります。"); } itemS = stS.split(","); sale = new HashMap<String, Object>(); sale.put("sales_date",itemS[0]); //売上日 sale.put("code",itemS[1]); //商品コード sale.put("amt",itemS[2]); //数量 sales.add(sale); // 売上データのproduct_codeを取得する。 Object product_code = sale.get( "code" ); if(hashTable.containsKey(product_code)){ //売上データと商品データを結合する。 sale.put( "product_name", product.get( "name" ) ); sale.put( "price", product.get( "price" ) ); // 売上データのcodeを取得する。 Object code = sale.get( "code" ); if ( ! resultsMap.containsKey( code ) ) { // マップにキーcodeが含まれていない // 集計結果の初期値を生成する。 result = new HashMap<String, Object>(); result.put( "code", code ); result.put( "amt", 0 ); result.put( "total", 0 ); // 生成した初期値をキーcodeに関連付けてマップに格納する。 resultsMap.put( code, result ); } // キーcodeに関連付く集計結果をマップから取得する。 result = resultsMap.get( code ); // 売上データのamtを集計結果に加算する。 int s_amt = Integer.valueOf((String) sale.get( "amt" )); int r_amt = Integer.valueOf((String) result.get( "amt" )); result.put( "amt", r_amt + s_amt ); // 売上データのpriceとamtとを掛けた値を集計結果に加算する。 int s_price = Integer.valueOf((String) sale.get( "price" )); int r_total = Integer.valueOf((String) result.get( "total" )); result.put( "total", r_total + s_price * s_amt ); String n =(String) product.get( "name" ); String a = (String) sale.get( "amt" ); int sum = s_price * s_amt; bwO.write( n + "," + a + "," + sum); bwO.newLine(); }else{ Object no = noItem; //商品名=商品マスタ未存在 bwO.write( no + "," + "," + ","); bwO.newLine(); } }//while for(int i=0; i<resultsMap.size(); i++){ //売上金額を昇順に並べ替え for(int j=i+1; j < resultsMap.size(); j++){ if(resultsMap(i) < resultsMap(j)){ int temp=resultsMap(i); resultsMap(i)=resultsMap(j); resultsMap(j)=temp; } } } bwO.write("商品名" + "," + "合計数量" + "," + "合計売上高"); bwO.newLine(); for(int i=0; i < resultsMap.size(); i++){ //売上金額順に出力 String n =(String) product.get( "name" ); bwO.write(n + "," + s_price + "," + r_total ); bwO.newLine(); } }catch(IOException e){ e.printStackTrace(); } }catch(IOException e){ System.err.println("何らかのエラーが発生しました。"); }finally{ try { brP.close(); brS.close(); bwO.close(); } catch (IOException e) { e.printStackTrace(); } } }//main }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

やりたいことは整理するべきです。
すべてのことをmainメソッドでやるのではなく処理を分割しましょう。
・商品一覧を作成するメソッド
・売上一覧を作成するメソッド
・商一覧と売上一覧を結合するメソッド
・ソートするメソッド
・Objectを多用しすぎです、商品クラスや売上クラスなどを作ってプログラムを整理しましょう。
上記の一つ一つを考えるなら難易度が下がると思いませんか?

最初からすべてのことを考えてプログラムを作ることは困難です。
分割し、整理しながら作りましょう。

投稿2016/03/27 17:44

編集2016/03/27 17:45
yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lena

2016/03/28 14:12

yonaさん、ご回答ありがとうございます。 確かにやりたいことが整理出来ておらず、混沌としたソースコードになっていると思います。メソッド分割をしたりクラスを分けるべきだとは思うのですが、正直に言ってどのようにメソッドやクラスを作るのか分からないのです。 よろしければ上記の内の一つを例にあげて教えていただけないでしょうか? どうぞよろしくお願いいたします。
yona

2016/03/28 14:31

メソッド分割の考え方だけ説明します。 下記のプログラムをコメントアウトしてください。これらは商品一覧に関連するローカル変数だと思われます。 BufferedReader brP = null; List<Map<String, Object>> products = new ArrayList<Map<String, Object>>(); Map<String, Object> product = null; String stP = ""; String[] itemP = null ; エラーが発生するはずです。 このエラーが発生した箇所が「商品一覧を作成している」可能性がある箇所です。このエラーになっている部分を別メソッドに切り分けてください。
lena

2016/03/28 16:10

yonaさん、再度ご回答ありがとうございます。 教えて下さったヒントをもとに下記のようにメソッドに切り分けてみました。 /** * 商品一覧を作成するメソッド */ public static void productList(){ BufferedReader brP = null; List<Map<String, Object>> products = new ArrayList<Map<String, Object>>(); Map<String, Object> product = null; String stP = ""; //inPファイルデータを格納 String[] itemP = null ; //inPファイルデータを配列に格納 try{ brP = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Users/temp/Desktop/inP.csv"),"JISAutoDetect")); }catch(FileNotFoundException e){ System.err.println("inP.csvファイルが見つかりません。"); } //inPファイルデータを読み込み while((stP = brP.readLine()) != null){ if(stP.equals("")){ System.err.println("データに不備があります。"); } itemP = stP.split(","); product = new HashMap<String, Object>(); product.put("code",itemP[0]); //商品コード product.put("name",itemP[1]); //商品名 product.put("price",itemP[2]); //単価 products.add(product); } for ( int i = 0; i < products.size(); ++i ) { product = products.get( i ); // 商品データのcodeを取得する。 Object key = product.get( "code" ); // codeをキーとして、商品データをハッシュテーブルに格納する。 hashTable.put( key, product ); } } このように引数なし、戻り値なしのメソッドでよろしいでしょうか?
yona

2016/03/28 16:27

戻り値はあったほうがいいですね。List<Map<String, Object>>を戻しますが、新しく商品クラス「Product」を作って、List<Product>を返すべきでしょう。 このクラスは「商品コード」、「商品名」、「単価」をフィールドに持っています。
lena

2016/03/31 01:20

yonaさん、ご回答ありがとうございます。 下記のように商品クラス「Product」を作成しました。 package lessons; class Product { /** 商品コード */ public String itemCode = null; /** 商品名 */ public String itemName = null; /** 単価 */ public int unitPrice = 0; } けれども、このクラスを使ってどのようにproductList()メソッドに組み入れるのか考えましたが全く分かりませんでした。 きっと、新しく商品クラスを作るべき目的が理解できないからだと思います。 この件に関して、どのような勉強をすれば理解できるようになるのでしょうか? それから、戻り値がなかったとしても問題はなさそうですが、どうして戻り値はあるほうがよろしいのでしょうか? 初歩的なご質問かと思いますが教えていただけないでしょうか、よろしくお願いいたします。
yona

2016/03/31 01:35

クラスを作る理由 List<Map<String, Object>> productsを List<Product> productsに変更できます。 こうすることで、Keyによって取得していた値をフィールドから取得することができるようになります。 戻り値が必要な理由 参照される範囲が広い、フィールド変数を書き換えるメソッドを作ると影響範囲が広くなるため、問題が発生した時に原因を特定しにくくなります。 勉強すると理解できるかについて 知識と経験です。言語仕様についての知識やリファスタリングについての知識が必要になります。 人に聞くのもいいでしょう。
lena

2016/04/01 10:05

yonaさん、クラスを作る理由や戻り値が必要な理由を教えていただきありがとうございました。 何度もご質問し申し訳ありませんが、下記内容について教えていただけないでしょうか? List<Map<String, Object>> productsを List<Product> productsに変更したら、 products.add((Product) product); ↑ この部分で 「java.util.HashMap cannot be cast to lessons.Product」とエラーが表示されるのですがどのように対処すればよろしいでしょうか?
guest

0

問題が多すぎて、混乱されているように見受けられます。
そもそも全ての問題を一度に解決しようとするのは、問題解決の手順としては一般に良い結果を生みません。

再優先で解決すべき問題はどれでしょうか?
そもそも実行時エラーが出て表示されないということでしょうか?

エラーで実行できない…という前提で書きます。

Java

1// 集計結果の初期値を生成する。 2result = new HashMap<String, Object>(); 3 4/* 5 *途中省略 6 */ 7 8// 売上データのamtを集計結果に加算する。 9int s_amt = Integer.valueOf((String) sale.get( "amt" )); 10int r_amt = Integer.valueOf((String) result.get( "amt" )); 11result.put( "amt", r_amt + s_amt ); // ←Objetc型にint型を代入しようとしてエラーになっていると思います。

説明はコードのコメント通りです。
下記のように修正してください。

Java

1Integer s_amt = Integer.valueOf((String) sale.get( "amt" )); 2Integer r_amt = Integer.valueOf((String) result.get( "amt" ));

投稿2016/03/27 17:13

Odacchi

総合スコア907

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lena

2016/03/28 14:24

Odacchiさん、ご回答ありがとうございます。 一番解決したい問題は、商品別の大きい合計金額順に並び替えをするために商品マスタと売上明細のデータを結合し蓄積していくメソッドを作りたいのですが、どのように作成すればよろしいでしょうか? ご回答いただけると幸いです。
Odacchi

2016/03/29 02:57

問題を分割し、シンプルな問題が複数あると考えましょう。 データを蓄積するというのはCSVファイルに対してですよね? 1つのメソッドは「~をする」メソッドと、動詞は1つが理想(そのほうがシンプルに実装できて、可読性、保守性も高い)です。 下記は例ですが、 ・商品マスタと売上明細のデータを結合するメソッド(戻り値はString?)(引数は?) ・CSVに蓄積するメソッド(引数はファイル名?)(戻り値はCSVにファイルを格納できたかどうかを表すboolean?) ・CSVファイルを並び替えするメソッド など、問題を分割して考えましょう!
lena

2016/03/31 02:47

Odacchiさん、メソッド作成時の注意点を教えていただきありがとうございました。 メソッドは「~をする」メソッドと、動詞は1つが理想なんですね。 そして、引数はメソッドに渡すデータのことで、戻り値は呼び出したメソッドの処理結果を返すものですよね。 その理解はあるものの、実際メソッドを作ろうとするとなぜか作れないのです。 何が原因で作れないのでしょうか? ご回答いただけると幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問