2009-06-21 4 views
2

編集:私のリストは、DBから来ているようにソートされています 私は、クラスのオブジェクトを持つArrayListを持っています。人々には、ssnとterminationReasonの2つのプロパティがあります。だから私のリストには、私は何の重複と終了の理由は、カンマで区切られがないように、このリストを変更したいこのどのようにJavaでリストを操作する

ArrayList: 
ssn   TerminatinoReason 
123456789  Reason1 
123456789  Reason2 
123456789  Reason3 
568956899  Reason2 
000000001  Reason3 
000000001  Reason2 

のように見えます。そのリストの上

は私が元のリストとのマッチングSSN年代をループしていますが、動作していないように行く何かを持っている

New ArrayList: 
ssn   TerminatinoReason 
123456789  Reason1, Reason2, Reason3 
568956899  Reason2 
000000001  Reason3, Reason2 

なります。

誰かが助けることができますか?私が使っていた

コードはでした:

String ssn = ""; 
    Iterator it = results.iterator(); 
    ArrayList newList = new ArrayList(); 
    People ob; 
    while (it.hasNext()) 
    { 
     ob = (People) it.next(); 
     if (ssn.equalsIgnoreCase("")) 
     { 
      newList.add(ob); 
      ssn = ob.getSSN(); 
     } 
     else if (ssn.equalsIgnoreCase(ob.getSSN())) 
     { 
      //should I get last object from new list and append this termination reason? 
      ob.getTerminationReason() 
     } 
    } 
+1

リストをループしているコードを表示できますか? – rogeriopvl

+0

リストをループしている箇所にコードを追加しました –

+0

データベースクエリがdupを削除できるようにすることで、Javaコードでそれらを処理する必要がなくなります。通常、データベースで行うことは、はるかに効率的です。 – rich

答えて

3
List<People> newlst = new ArrayList<People>(); 
People last = null; 
for (People p : listFromDB) { 
    if (last == null || !last.ssn.equals(p.ssn)) { 
     last = new People(); 
     last.ssn = p.ssn; 
     last.terminationReason = ""; 
     newlst.add(last); 
    } 
    if (last.terminationReason.length() > 0) { 
     last.terminationReason += ", "; 
    } 
    last.terminationReason += p.terminationReason; 
} 

そして、あなたはnewlstで集約されたリストを取得します。

更新: MySQLを使用している場合は、GROUP_CONCAT関数を使用して、必要な形式でデータを抽出できます。他のDBエンジンにも同様の機能があるのか​​どうかわかりません。

更新2:不要な並べ替えを削除しました。

3

ハッシュが必要な場合があります。おそらくHashMapを使用することができます。

Peopleクラス内でequals()およびhashCode()をオーバーライドします。

hashCodeは、人(人物)のSSNを返します。このようにして、同じSSNを持つすべてのPeopleオブジェクトを同じ「バケット」内に配置することができます。

Mapインターフェイスの実装クラスでは、オブジェクトを保持するためにキーと値のペアを使用するので、myHashMap.add( "ssn"、peopleobject)のようになります。

1

二つの可能性のある問題:

  • これはあなたのリストは
  • にソートされていない場合は、ob.getTerminationReason()で何もしていない動作しません。以前のオブジェクトに追加することを意味すると思います。
0

編集:今、私はあなたの質問を編集しました。

リストがソートされるので、(私は推測SSNによる)

Integer currentSSN = null; 
List<People> peoplelist = getSortedList();//gets sorted list from DB. 
/*Uses foreach construct instead of iterators*/ 

for (People person:peopleList){ 

if (currentSSN != null && people.getSSN().equals(currentSSN)){ 
//same person 
system.out.print(person.getReason()+" ");//writes termination reason 

} 
else{//person has changed. New row. 
    currentSSN = person.getSSN(); 
    system.out.println(" ");//new row. 
    system.out.print(person.getSSN()+ " ");//writes row header. 
} 

} 

あなたのリストの内容を表示したいドント場合は、MAPを作成し、それを使用するためにそれを使用することができます以下に示すように。あなたのリストが

にソートされていない場合

たぶん、あなたは地図を使って、別のアプローチを試してみてください。ここでは、SSNは、マップのキーとなり、その値は、人々

Map<Integer,List<People>> mymap = getMap();//loads a Map from input data. 

for(Integer ssn:mymap.keyset()){ 
dorow(ssn,mymap.get(ssn)); 
} 

public void dorow(Integer ssn, List<People> reasons){ 

system.out.print(ssn+" "); 
for (People people:reasons){ 
system.out.print(people.getTerminationReason()+" "); 
} 

system.out.println("-----");//row separator. 

なく、少なくとも最後に、あなたはあなたののhashCode()とequals(ピープルクラスの)メソッドをオーバーライドする必要がありますの一覧である可能性があります。私に

例えば

public void int hashcode(){ 

    return 3*this.reason.hascode(); 

} 
+0

...新しいオブジェクトにpersonオブジェクトを追加しますか?私が 'else'に追加すると、 'if'のオブジェクトを何とか更新する必要があります... –

5

、これは一つのキーに複数の値を格納できるようになるMultimapを、使用することが良い場合のように思えます。

Google Collectionsは、Multimapの実装を持っています。

これはPersonオブジェクトのssnterminationReasonフィールドはそれぞれ、キーと値であることを取り出さなければならないかもしれないことを意味します。 (そして、それらのフィールドはStringであると仮定される。)

基本的に、それを使用することができる次のよう

Multimap<String, String> m = HashMultimap.create(); 

// In reality, the following would probably be iterating over the 
// Person objects returned from the database, and calling the 
// getSSN and getTerminationReasons methods. 

m.put("0000001", "Reason1"); 
m.put("0000001", "Reason2"); 
m.put("0000001", "Reason3"); 
m.put("0000002", "Reason1"); 
m.put("0000002", "Reason2"); 
m.put("0000002", "Reason3"); 

for (String ssn : m.keySet()) 
{ 
    // For each SSN, the termination reasons can be retrieved. 
    Collection<String> termReasonsList = m.get(ssn); 

    // Do something with the list of reasons. 
} 

を必要に応じて、Collectionのカンマ区切りリストを生成することができる。

StringBuilder sb = new StringBuilder(); 

for (String reason : termReasonsList) 
{ 
    sb.append(reason); 
    sb.append(", "); 
} 

sb.delete(sb.length() - 2, sb.length()); 
String commaSepList = sb.toString(); 

もう一度terminationReasonフィールドに設定できます。

コメントに記載されているように、Jonik氏はメソッドを使用して、Apache Commons Langのコンマ区切りリストを作成することもできます。

Multimapは、実装で重複するキーと値のペアを許可するかどうかを指定しないため、使用するタイプはMultimapである必要があります。

この例では、重複するキーと値のペアを許可しないため、HashMultimapを選択することをお勧めします。これにより、特定の1人の重複理由が自動的に解消されます。

+0

+1正確に。私は自分自身のMultimapの回答を投稿しようとしていましたが、今私はそれをスキップします。 :)私はコンマで区切られたリストのためにApache Commons LangからStringUtils.join()を使用します。 (そして、おそらく、オブジェクトリレーショナルマッピングは一般的に再考することができます。つまり、Javaを表現するJavaのオブジェクトは、その中にすべての理由があるはずです...) – Jonik

+0

@Jonik、StringUtils.join上のポインタに感謝します:)答えにそれを加えました。 (私は手で行うよりも良い方法がなければならないことを知っていました。)また、私は、Personオブジェクト自体が1人のPersonオブジェクトを複数持つよりも、複数の理由を持つ必要があることにも同意します。 – coobird

関連する問題