2016-12-22 5 views
0

誰も私が持っているコードで次の答えを得る方法を知っていますか?
複数のフィールドを持つ異なるクラス/ java docのArrayListの重複アイテムをカウントするにはどうすればよいですか?

AAA:3
BBB:2
CCC:1

1:2
2:2
3:1
4:1

ここで何でありますこれまでに試したことがあります:

これはメインクラスです

package tester1; 

    import java.util.ArrayList; 

    public class Tester1 { 


    public static void main(String[] args) { 
     tester t1 = new tester(1,"aaa"); 
     tester t2 = new tester(2,"aaa"); 
     tester t3 = new tester(2,"aaa"); 
     tester t4 = new tester(1,"ccc"); 
     tester t5 = new tester(3,"bbb"); 
     tester t6 = new tester(4,"bbb"); 
     ArrayList<tester> list = new ArrayList<tester>(); 
     list.add(t1); 
     list.add(t2); 
     list.add(t3); 
     list.add(t4); 
     list.add(t5); 
     list.add(t6); 

     test t = new test(list); 
     t.getter(); 
    } 

    } 

このコンストラクタはあなたがカウントを保存するためにMapを使用することができます

package tester1; 


public class tester { 

private int num; 
private String name; 

public tester(int num, String name) { 
    this.num = num; 
    this.name = name; 
} 

public int getNum() { 
    return num; 
} 

public String getName() { 
    return name; 
} 

} 
+0

あなたが間違っているものを代わりに 'Set' – Arvind

+1

の' Map'のために行くことができますあなたは現在何を持っていますか?何が出力されますか? – eis

+0

[List内の要素の出現回数を数える方法](http://stackoverflow.com/questions/505928/how-to-count-the-number-of-occurrences-of-an- element-in-a-list) –

答えて

0

ある場合、このクラスの配列リストに

package tester1; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.Set; 

public class test { 
private ArrayList<tester> testList; 

public test(ArrayList<tester> testList) { 
    this.testList = testList; 
} 
public void getter() 
{ 
    Set<tester>unique = new HashSet<tester>(testList); 
    for(tester key:unique) 
    { 
     System.out.println(key.getName()+": "+Collections.frequency(testList, key.getName())); 
    } 
} 
} 

を接続するためのクラス:

public Map<String,Integer> getCounts(ArrayList<Tester> list){ 

    Map<String,Integer> counter=new HashMap<String,Integer>(); 

    for(Tester s : list){ 

    if(counter.containsKey(s.getKey())){ 
     counter.put(s,counter.get(s.getKey())+1); 
    }else{ 
     counter.put(s.getKey(),1); 
    } 

    } 

    return counter; 

} 

今、あなたは単にあなたのマップを反復処理することができます印刷するには:

for(Map.Entry<String,Integer> entry : getCounts(list).entrySet()){ 
    System.out.println(entry.getKey() + " : " + entry.getValue(); 
} 
2

Collections#frequencyのjavadocのから:

は、指定したオブジェクトに等しい指定されたコレクション内の要素の数を返します。より正式には、(o == null?e == null:o.equals(e))のように、コレクション内の要素数eを返します。

なぜ、どこに0を出力しますか?与えられた契約は決してtrueに解決されないので、これは非常に単純です。TesterStringと等しくないためです。

正しい出力を得るには、equalshascodeを最初にTesterに上書きする必要があります。あなたは今の適切な出力(ただのammountでソートされていないがあります

// replaced key.getName() with key 
System.out.println(key.getName() + ": " + Collections.frequency(testList, key)); 

// both are generated by eclipse source generation for the field name. 
@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((name == null) ? 0 : name.hashCode()); 
    return result; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Tester other = (Tester) obj; 
    if (name == null) { 
     if (other.name != null) 
      return false; 
    } else if (!name.equals(other.name)) 
     return false; 
    return true; 
} 

は今、あなたはTesterなくTesternameフィールド上で動作するようにあなたのCollections#frequencyの呼び出しを変更する必要があります発生箇所):

bbb: 2 
aaa: 3 
ccc: 1 
+0

ありがとうございました。 – KUROYUKI

+0

テスターでチェックしたいフィールドが複数ある場合、何をする必要がありますか? intであれば何を変更する必要がありますか? – KUROYUKI

+0

@KUROYUKIあなたが実際に変更しなければならないことは、あなたの必要条件によって異なります。しかし、どこを変更する必要があるのか​​は 'hashCode'と' equals'です。あなたはそこにあなたのロジックを含める必要があります。 – SomeJavaGuy

0
list.stream() 
    .collect(Collectors.groupingBy(t -> t.getName(), Collectors.counting())) 
    .entrySet() 
    .stream() 
    .sorted(Map.Entry.<String, Long>comparingByValue().reversed()) 
    .forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())); 

どうすればStreamを試してみてはいかがですか? testクラスは必要ありません。 以下の2つの手順で達成できます。

  1. リスト内のすべての要素を発生回数でグループ化します。
  2. 生成されたマップを発生回数でソートします。ここで
0

一部を簡略化し、別のバージョンでは、ですが、いくつかの静的輸入品との短いラムダソリューションを示しています

import static java.util.function.Function.identity; 
import static java.util.stream.Collectors.counting; 
import static java.util.stream.Collectors.groupingBy; 

import java.util.Arrays; 
import java.util.List; 
import java.util.Map; 

public class Tester 
{ 

    public static void main(final String[] args) 
    { 
     final List<String> list = Arrays.asList("aaa", "aaa", "aaa", "ccc", "bbb", "bbb"); 
     final Map<String, Long> map = list.stream() 
              .collect(groupingBy(identity(), counting())); 
     System.out.println("map = " + map); 
    } 
} 
関連する問題