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

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

ただいまの
回答率

90.48%

  • Java

    14116questions

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

  • CSV

    675questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,126

lena

score 22

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


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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/28 23:12

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

    キャンセル

  • 2016/03/28 23:31

    メソッド分割の考え方だけ説明します。
    下記のプログラムをコメントアウトしてください。これらは商品一覧に関連するローカル変数だと思われます。
    BufferedReader brP = null;
    List<Map<String, Object>> products = new ArrayList<Map<String, Object>>();
    Map<String, Object> product = null;
    String stP = "";
    String[] itemP = null ;

    エラーが発生するはずです。
    このエラーが発生した箇所が「商品一覧を作成している」可能性がある箇所です。このエラーになっている部分を別メソッドに切り分けてください。

    キャンセル

  • 2016/03/29 01: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 );
    }
    }
    このように引数なし、戻り値なしのメソッドでよろしいでしょうか?

    キャンセル

  • 2016/03/29 01:27

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

    キャンセル

  • 2016/03/31 10:20

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

    キャンセル

  • 2016/03/31 10:35

    クラスを作る理由
    List<Map<String, Object>> productsを
    List<Product> productsに変更できます。
    こうすることで、Keyによって取得していた値をフィールドから取得することができるようになります。

    戻り値が必要な理由
    参照される範囲が広い、フィールド変数を書き換えるメソッドを作ると影響範囲が広くなるため、問題が発生した時に原因を特定しにくくなります。

    勉強すると理解できるかについて
    知識と経験です。言語仕様についての知識やリファスタリングについての知識が必要になります。
    人に聞くのもいいでしょう。

    キャンセル

  • 2016/04/01 19:05

    yonaさん、クラスを作る理由や戻り値が必要な理由を教えていただきありがとうございました。
    何度もご質問し申し訳ありませんが、下記内容について教えていただけないでしょうか?
    List<Map<String, Object>> productsを
    List<Product> productsに変更したら、
    products.add((Product) product);

    この部分で 「java.util.HashMap cannot be cast to lessons.Product」とエラーが表示されるのですがどのように対処すればよろしいでしょうか?

    キャンセル

+1

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

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

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

// 集計結果の初期値を生成する。
result = new HashMap<String, Object>();

/*
 *途中省略
 */

// 売上データの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 ); // ←Objetc型にint型を代入しようとしてエラーになっていると思います。

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/28 23:24

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

    キャンセル

  • 2016/03/29 11:57

    問題を分割し、シンプルな問題が複数あると考えましょう。
    データを蓄積するというのはCSVファイルに対してですよね?

    1つのメソッドは「~をする」メソッドと、動詞は1つが理想(そのほうがシンプルに実装できて、可読性、保守性も高い)です。

    下記は例ですが、
    ・商品マスタと売上明細のデータを結合するメソッド(戻り値はString?)(引数は?)
    ・CSVに蓄積するメソッド(引数はファイル名?)(戻り値はCSVにファイルを格納できたかどうかを表すboolean?)
    ・CSVファイルを並び替えするメソッド

    など、問題を分割して考えましょう!

    キャンセル

  • 2016/03/31 11:47

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

    キャンセル

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    14116questions

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

  • CSV

    675questions

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