ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

プログラマたまごくらぶコミュの【JAVA】コンパイルもJSPエラーもないんですがソートができません。

  • mixiチェック
  • このエントリーをはてなブックマークに追加
JAVAでJSPのデータをソートしている時に起こりました。
バブルソートをsort()やツリーマップを使わずに実行しているのですが、同一の項目名があった場合にビットマップから検索している関係でうまくソートできませんでした。
で、それを直すために二次元配列にデータを入れてビットマップに入れる方式を使ったんです。

ところがうまくソートされない。
コンパイルもJSPエラーも発生してませんが中途半端にソートされます。
例:6 10 4 9→4 6 10 9
のような感じです。
で、いじっていたらソートする時の最初に見る場所(私のソースの場合は一番右と右から二番目を比べます)の配列の指定を少し変えたら直りました。

で、ここからが問題です。

一番右を見る
//String right=(String)aa3.get(migi);
String right=(String)key[migi][1];

右から二番目を見る
//String left=(String)aa3.get(migi-1);
String left=(String)key[migi-1][1];

上のコードの値はコメントを逆にしても同じ値になります。
にもかかわらずコメントを逆にすると先ほどのような症状になります。研修先の社員さんもソースを見て考えてみるそうですが私にはまったくわかりません。
なぜ動いたのか検証していただけると幸いです。
プロになるならただ動けばいいのではなくなぜ動いたのかを考えないといけないと思うのでいっしょに考えましょう。

コメント(5)

補足です。
aa3というのはSVCの縦一列が入ったArrayListです。
key[][]というのが二次元配列。
左の[]にユニークなKEYとなる数字
右の[]にaa3のデータを入れています。

その他分かりにくいところがあればコメントします。
なんか昨日書いた内容にかなり間違いがあったみたいなので訂正。
まずソートしているのはCSVファイルでした。
あと二次元配列を入れるのがHashMapです。

全ソースも公開してみます。

package kadai2;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

public class sort extends HttpServlet
{
  public void doGet(HttpServletRequest req,
  HttpServletResponse res)
  throws ServletException,IOException
  {
   //セッションがなければ作成
   HttpSession session=req.getSession(true);
   req.setCharacterEncoding("Shift_JIS");//文字コード
   ServletContext context=getServletConfig().getServletContext();
   String str=null;
   try
   {
    //CSVファイルの読み込み
    BufferedReader br=new BufferedReader
    (new FileReader(context.getRealPath("PC.csv")));

    str=br.readLine();//ファイルの先頭行を読む
    //カンマと文字を分ける
    StringTokenizer st=new StringTokenizer(str,",");
    //カンマのない数字だけの列をTopのJSPに送る
    session.setAttribute("st",st);
    session.setAttribute("br",br);//TopのJSPに送る
    br.close();//ファイルの読み込みを終了
    //Topへ遷移
    res.sendRedirect("/studyServlet/jsp/top2.jsp");
   }
   catch(IOException e)//例外処理
   {
    session.setAttribute("error","入出力エラーが発生しました");
   }
  }
  public void doPost(HttpServletRequest req,
  HttpServletResponse res)
  throws ServletException,IOException
  {
   //セッションがなければ作成
   HttpSession session=req.getSession(true);
req.setCharacterEncoding("Shift_JIS");//文字コード
ServletContext context=getServletConfig().getServletContext();
System.out.println("ここからソートのプログラム開始----------------");

String so1=(String)req.getParameter("sort");//ソートする項目をjspからとる
int sor1=Integer.parseInt(so1);//int型に変更する
ArrayList aa1=new ArrayList();
ArrayList aa2=new ArrayList();
ArrayList aa3=new ArrayList();
aa1=(ArrayList)session.getAttribute("a1");//項目のArrayList
aa2=(ArrayList)session.getAttribute("a2");//データのArrayList
for(int j=sor1;j<aa2.size();)//初期値を項目の値とし、データ数がある限りまわす
{
aa3.add(aa2.get(j));//ArrayListにaa2の中からソートしたい項目部分だけを入れる
j=j+aa1.size();//初期値に項目数を足す
}
String kai=null;//kaiは行をあらわす
ArrayList a4=new ArrayList();
for(int j=0;j<aa2.size();j++)//jをデータ数があるだけまわす
{
if(j%(aa1.size())==0)//jを項目数で割ったら余りが0の時
{
if(kai!=null)
{
a4.add(kai);//ArrayListに行を入れる
}
kai=(String)aa2.get(j);//kaiにその時のデータを入れる
}
else
{
kai=kai+","+(String)aa2.get(j);//kaiにkai+データ
}
//最後の行だけ次の行にいけないのでデータの最後を読み取ってArrayListに格納する
if(j==aa2.size()-1)
{
a4.add(kai);
}
}
HashMap hm=new HashMap();//HashMapを初期化
ArrayList aa5=new ArrayList();
System.out.println("サイズは"+aa3.size());
String[][]key=new String[aa3.size()][2];
for(int c=0;c<aa3.size();)
{
String c2=String.valueOf(c);
for(int d=0;d<=1;d++)
{
if(d==0)
{
System.out.println("ddaxo"+d);
key[c][d]=c2;
}
else
{
System.out.println("ddesu"+d);
key[c][d]=(String)aa3.get(c);
c++;
}
}
}
for(int aaa=0;aaa<aa3.size();aaa++)
{
System.out.println("始まりは"+key[aaa][0]+","+key[aaa][1]);
}
System.out.println(key[0].length);
for(int k=0;k<aa3.size();k++)
{
//hm.put(aa3.get(k),a4.get(k));
//ハッシュマップにソートしたい項目と一行セットを関連付けて入れる
hm.put(key[k][0]+","+key[k][1],a4.get(k));
//ハッシュマップにソートしたい項目と一行セットを関連付けて入れる
//System.out.println(key[k][0]);
//System.out.println(key[k][1]);
}
for(int hidari=0;hidari<aa3.size()-1;hidari++)
//左端の配列からひとつずつ右へ行く。右端の1個手前までいく。
{
for(int migi=aa3.size()-1;hidari<migi;migi--)
//右端の配列から左方向へ見ていく
{
//System.out.println("最初に入った時の右は"+migi);
System.out.println("だめな場合はこっち="+aa3.get(migi));
System.out.println("成功した場合はこっち="+key[migi][1]);
//String right=(String)aa3.get(migi);
String right=(String)key[migi][1];
//String left=(String)aa3.get(migi-1);
String left=(String)key[migi-1][1];
System.out.println("パターンA成功"+key[migi-1][1]);
System.out.println("パターンB失敗"+aa3.get(migi-1));
try//キーワードが数字なら
{
int rr=Integer.parseInt(right);
int le=Integer.parseInt(left);
if(rr<le)//これを逆にすると降順になる
{
/*
        String kari=(String)aa3.get(migi);//仮に右側の値を入れる
        aa3.remove(migi);//挿入する前に行を削除しておく
        aa3.add((migi),aa3.get(migi-1));//右側に左側の値を入れる
        aa3.remove(migi-1);//挿入する前に行を削除しておく
        aa3.add((migi-1),kari);//左側に仮(右側)の値を入れる
        */
        System.out.println("migi"+migi);
        System.out.println("ソート開始");
        String kari=(String)key[migi][0];
        System.out.println(kari);
        String kari2=(String)key[migi][1];
        //System.out.println(kari2);
        key[migi][0]=(String)key[migi-1][0];
        System.out.println(key[migi][0]);
        key[migi][1]=(String)key[migi-1][1];
             //System.out.println(key[migi][0]);
        key[migi-1][0]=kari;
        key[migi-1][1]=kari2;
        System.out.println(key[migi-1][0]);
             //System.out.println(key[migi-1][1]);
      }
     }
     catch(NumberFormatException e)
//キーワードが文字の場合errorが発生するのでこの処理をする
     {
       if(right.compareTo(left)<0)
//右側とその一つ前を比べる compareToは右側が大きいとき負の数を返す
        {
         /*
         String kari=(String)aa3.get(migi);
//仮に右側の値を入れる
         aa3.remove(migi);//挿入する前に行を削除しておく
         aa3.add((migi),aa3.get(migi-1));//右側に左側の値を入れる
         aa3.remove(migi-1);//挿入する前に行を削除しておく
         aa3.add((migi-1),kari);//左側に仮(右側)の値を入れる*/

         String kari=(String)key[migi][0];
         String kari2=(String)key[migi][1];
         key[migi][0]=(String)key[migi-1][0];
         key[migi][1]=(String)key[migi-1][1];
         key[migi-1][0]=kari;
         key[migi-1][1]=kari2;
        }
     }
    }
   }
   for(int m=0;m<aa3.size();m++)
   {
    //System.out.println("結果は"+key[m][0]+","+key[m][1]);
    //System.out.println("終わってみたら"+key[5][0]+","+key[5][1]);
    //StringTokenizer st=new StringTokenizer(((String)hm.get(aa3.get(m))),",");
//カンマ区切りのstrをカンマの部分まででひとつのトークンとする
    StringTokenizer st=new StringTokenizer
    (((String)hm.get(key[m][0]+","+key[m][1])),",");
//カンマ区切りのstrをカンマの部分まででひとつのトークンとする
    while(st.hasMoreTokens())
//1行の中にまだ文字(単語)が残っているか調べる
    {
     aa5.add(st.nextToken());//データをArrayListに格納する
    }
   }
   session.setAttribute("a2",aa5);
   System.out.println("ここでソートのプログラム終了----------------");
   res.sendRedirect("/studyServlet/jsp/top2.jsp");
  }
}
はじめまして。
javaは未経験ですが、気になった点を書きます。

for文のループ回数は、配列の数だけ回ってますか?
右の2列目からソートをかけていませんか?


//for(int hidari=0;hidari<aa3.size()-1;hidari++)
//左端の配列からひとつずつ右へ行く。右端の1個手前まで
//いく。

配列分回っていないと思うので、「aa3.size()-1」から「-1」を取ってみてください。

よろしくお願いします。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

プログラマたまごくらぶ 更新情報

プログラマたまごくらぶのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング