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

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

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

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

Java

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

Q&A

解決済

1回答

2672閲覧

ソートしたデータの抽出方法を教えてください。

lena

総合スコア31

CSV

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

Java

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

0グッド

0クリップ

投稿2016/03/23 06:21

JAVA初心者です。
月別の売上金額の大きい3商品を出力するプログラムを
作成しています。

【完成例】
商品名,数量 ,売上金額 ,備考
201601月売上高BEST3
バナナ,10,100,
玉ねぎ,8,80,
トマト,6,60,
201602月売上高BEST3
バナナ,15,150,
玉ねぎ,14,140,
白菜,10,110,
商品マスタ未存在,,,
,,,日付に誤りがあります

【今現在】
商品名,数量 ,売上金額 ,備考
201601月売上高BEST3
カボチャ,10,100,
カボチャ,8,80,
カボチャ,6,60,
商品マスタ未存在,,,
,,,日付に誤りがあります

【仕様内容】
売上明細をもとに商品マスタより商品名と単価を取得します。
売上金額の大きい商品の順に出力します(sortメソッドは使用しない)。
商品の出力まえに「yyyymm月売上高BEST3」を出力します。

【分からない点】
①並び替えをした商品名を抽出するにはどうすればよろしいでしょうか?
②2月のデータが出力されないのはどうしてでしょうか?
完成例を実現する方法を教えてください。
どうぞよろしくお願いいたします。

package lesson; 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.text.DateFormat; import java.text.SimpleDateFormat; import java.util.HashMap; public class MonthlySalesBest3 { public static void main(String[] args) { BufferedReader brM = null ; //商品マスタ入力ファイル BufferedReader brA = null ; //売上明細入力ファイル BufferedWriter bwA = null ; //月額売上表出力ファイル String stM = ""; //inMファイルデータを格納 String stA = ""; //inAファイルデータを格納 HashMap<String,HashMap<String,Object>> alDM = new HashMap<String,HashMap<String,Object>>() ; //商品マスタの入力データを格納 HashMap<String, Object> mpDM = null; String[] itemM ; //inMファイルデータを配列に格納 String[] itemA; //inAファイルデータを配列に格納 String date = ""; //売上明細ファイルの購入月をセット boolean isFirst = true; //0番目の購入日をセットする為の変数 int amt1 = 0; //バナナの合計数量 int amt2 = 0; //玉ねぎの合計数量 int amt3 = 0; //トマトの合計数量 int amt4 = 0; //白菜の合計数量 int amt5 = 0; //カボチャの合計数量 int sum1= 0; //バナナの合計金額 int sum2= 0; //玉ねぎの合計金額 int sum3= 0; //トマトの合計金額 int sum4= 0; //白菜の合計金額 int sum5= 0; //カボチャの合計金額 int allSum1= 0; //バナナの月の合計金額 int allSum2= 0; //玉ねぎの月の合計金額 int allSum3= 0; //トマトの月の合計金額 int allSum4= 0; //白菜の月の合計金額 int allSum5= 0; //カボチャの月の合計金額 final String noItem = "商品マスタ未存在"; final String noCalendar = "日付に誤りがあります"; boolean emptyflgM = false; //商品マスタファイル空判定フラグ boolean emptyflgA = false; //売上明細入力ファイル空判定フラグ try{ fileError:{ try{ brM = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Users/temp/Desktop/inM.csv"),"JISAutoDetect")); }catch(FileNotFoundException e){ System.err.println("inM.csvファイルが見つかりません。"); } try{ brA = new BufferedReader(new InputStreamReader(new FileInputStream("C:/Users/temp/Desktop/inA.csv"),"JISAutoDetect")); }catch(FileNotFoundException e){ System.err.println("inA.csvファイルが見つかりません。"); } try{ bwA = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:/Users/temp/Desktop/outA.csv"),"SJIS")); }catch(FileNotFoundException e){ System.err.println("outA.csvファイルが見つかりません。"); } //inMファイルデータを読み込み while((stM = brM.readLine()) != null){ if(stM.equals("")){ System.err.println("データに不備があります。"); break fileError; } emptyflgM = true; itemM = stM.split(","); mpDM = new HashMap<String,Object>(); mpDM.put("code",itemM[0]); mpDM.put("name",itemM[1]); mpDM.put("price",itemM[2]); alDM.put(itemM[0],mpDM); }//while if(emptyflgM == false){ System.err.println("inMファイルが空です。"); break fileError; } bwA.write("商品名" + "," + "数量" + " ," + "売上金額" + " ," + "備考"); bwA.newLine(); try{ while((stA = brA.readLine()) != null){ if(stA.equals("")){ System.err.println("データに不備があります。"); break fileError; } emptyflgA = true; itemA = stA.split(","); mpDM = alDM.get(itemA[1]); if(isFirst){ date = itemA[0].substring(0, 6); isFirst = false; } String soldDay = (itemA[0].substring(0, 6)); int sold= soldDay.compareTo(date); //月変更の比較 int[] allSums = {allSum1,allSum2,allSum3,allSum4,allSum5}; //全商品の月の合計金額を格納 int[] amts = {amt1,amt2,amt3,amt4,amt5}; //全商品の月の合計数量を格納 if(sold > 0){ bwA.write(date.substring(0, 6) + "月売上高BEST3"); //月売上高BEST3を出力 bwA.newLine(); for(int i=0; i<allSums.length-1; i++){ //売上金額を昇順に並べ替え for(int j=i+1; j<allSums.length; j++){ if(allSums[i]<allSums[j]){ int temp=allSums[i]; allSums[i]=allSums[j]; allSums[j]=temp; } } } for(int i=0; i < 3; i++){ Object b = mpDM.get("name"); //商品名 int c = amts[i]; //数量 int d = allSums[i]; //数量 //Object d = mpDataM.get("price"); //単価 bwA.write(b + "," + c + "," + d + ","); bwA.newLine(); } date = itemA[0]; //売上日を再セット amt1 = 0; //バナナの合計数量を0に戻す amt2 = 0; //玉ねぎの合計数量を0に戻す amt3 = 0; //トマトの合計数量を0に戻す amt4 = 0; //白菜の合計数量を0に戻す amt5 = 0; //カボチャの合計数量を0に戻す sum1= 0; //バナナの合計金額を0に戻す sum2= 0; //玉ねぎの合計金額を0に戻す sum3= 0; //トマトの合計金額を0に戻す sum4= 0; //白菜の合計金額を0に戻す sum5= 0; //カボチャの合計金額 allSum1 = 0; // バナナの月合計を0に戻す allSum2 = 0; // 玉ねぎの月合計を0に戻す allSum3 = 0; // トマトの月合計を0に戻す allSum4 = 0; // 白菜の月合計を0に戻す allSum5 = 0; // カボチャの月合計を0に戻す } if(alDM.containsKey(itemA[1])){ //String c = itemA[2]; //数量 String d = (String) mpDM.get("price"); //単価 String e = ""; //備考 if(checkDate(itemA[0])){ //日付の妥当性を確認 int num = Integer.parseInt(itemA[2]); int num2 = Integer.parseInt((String) d); switch (itemA[1]){ case "0001": amt1 = amt1 + num; sum1 = num * num2; allSum1 = sum1 + allSum1; //System.out.println(itemA[1]); break; case "0002": amt2 = amt2 + num; sum2 = num * num2; allSum2 = sum2 + allSum2; //System.out.println(itemA[1]); break; case "0003": amt3 = amt3 + num; sum3 = num * num2; allSum3 = sum3 + allSum3; //System.out.println(itemA[1]); break; case "0004": amt4 = amt4 + num; sum4 = num * num2; allSum4 = sum4 + allSum4; //System.out.println(itemA[1]); break; case "0005": amt5 = amt5 + num; sum5 = num * num2; allSum5 = sum5 + allSum5; //System.out.println(itemA[1]); break; } } else{ e = noCalendar; //備考=日付に誤りがあります bwA.write( "," + "," + "," + e); bwA.newLine(); } }else{ //String a = itemA[0]; //購入日 Object b = noItem; //商品名=商品マスタ未存在 //String c = itemA[2]; //数量 bwA.write( b + "," + "," + ","); bwA.newLine(); } }//while if(emptyflgA == false){ System.err.println("inA.csvファイルが空です。"); break fileError; } }catch(IOException e){ e.printStackTrace(); } }//fileError }catch(FileNotFoundException e){ System.err.println("ファイルが見つかりません。"); }catch(IOException e){ System.err.println("何らかのエラーが発生しました。"); } finally{ try { brA.close(); brM.close(); bwA.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 日付の妥当性をチェック * カレンダーに存在するかどうかを返す。 * 存在する日付の場合true */ public static boolean checkDate(String strDate) { if (strDate == null || strDate.length() != 8) { throw new IllegalArgumentException( "引数の文字列["+ strDate +"]" + "は不正です。"); } DateFormat format = new SimpleDateFormat("yyyyMMdd"); format.setLenient(false); try { format.parse(strDate); return true; } catch (Exception e) { return false; } } }

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

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

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

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

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

guest

回答1

0

ベストアンサー

「mpDM = alDM.get(itemA[1]);」してるところで商品名を格納したMapを取ろうとしてるのはわかったけど、肝心の商品名を出力するとこ(「Object b = mpDM.get("name"); //商品名」)で同じmpDMを参照してるから同じ商品名が出るのです。

以下追記:

「並べ替えする数字」と「数字と対になる名前」は同じようにソートしてあげないとだめです。
金額・個数をセットにしてあれこれするのであれば、下のような独自クラスを作ってあげるのも手。

class Profit { /** 商品名 */ public String itemName = null; /** 売上数量 */ public int count = 0; /** 売上金額 */ public int salesAmount = 0; }

これを名前とセットで管理すれば同じように並べ替えができますよ。

HashMap<String, Profit> totalHolder = null; // boolean isFirst = true; while((stA = brA.readLine()) != null){ itemA = stA.split(","); if(isFirst){ date = itemA[0].substring(0, 6); isFirst = false; } String soldDay = (itemA[0].substring(0, 6)); // 月変更の比較 // 同じ月じゃなかったら今までため込んでた分を並べ替え&出力、でしょ? if(soldDay.equals(date) == false){ // ここで並べ替え&出力:処理が長くなるのでさらに下の方で記述予定 // totalHolderの初期化 totalHolder = null; } if(totalHolder == null){ totalHolder = new HashMap<String, Profit>(); } mpDM = alDM.get(itemA[1]); //↑itemA[1]がなんなのかよくわかりませんが、ともあれこれでマスタが取れましたね。 String itemName = mpDM.get("name"); if(totalHolder.containsKey(itemName == false) { //totalHolderに名前が登録されてなければ新しく登録します。 totalHolder.put(itemName, new Profit()); totalHolder.get(itemName).itemName = itemName; // あとで値出力の時に使う } // これで数字の加算。 totalHolder.get(itemName).count += totalHolder.get(itemName).salesAmount += }

並べ替えの時にはMap#values()を使うとCollection型ですべての値が取得できるので、これをtoArray()してから並べ替えます。

Profit[] arr = totalHolder.values().toArray(new Profit[]);

後の並べ替え自体はProfit#salesAmountを比較していけばできますよね?

投稿2016/03/23 06:56

編集2016/03/23 08:15
tkturbo

総合スコア5572

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

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

lena

2016/03/23 07:11

tkturboさん、ご回答ありがとうございます。 なぜ同じ商品名が出力されるのか分かりましたが、どうすればソートされた商品名を抽出できるのか、いろいろと試しましたが結局分かりませんでした。 よろしくお願いいたします。
tkturbo

2016/03/23 08:16

長くなりそうだったので回答を編集しました。
lena

2016/03/23 18:42

tkturboさん、ご回答ありがとうございます。 丁寧にご説明いただきありがとうございました。 >「並べ替えする数字」と「数字と対になる名前」は同じようにソートしてあげないとだめです。 確かにそうですね、気づきませんでした。 ですがメソッド分割やクラスを分ける方法をまだ分からないので、ご説明いただいた内容をちゃんと理解するのは少々時間がかかりそうですが使いこなせるように頑張って勉強したいと思います。 一つご質問があるのですが、並べ替えをソート機能を使わずロジックで考えて実装するにはどうすればよろしいでしょうか? お応えいただけると幸いです。
lena

2016/03/25 04:25

tkturboさん、教えて下さりありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問