2016-04-11 70 views
14

因此,讓我們假設我有一個對象AnimalArraylist。這個類的對象是這樣的:使用java計算列表中的對象的屬性8

class Animal{ 
    String Name;//for example "Dog" 
    String Color 
} 

我想要做的,是數不同的顏色在ArrayList每個動物存在多少並把它們放在一個Map<String,Integer>其中String是名稱和Integer是不同顏色的數量。

例如,如果有4種黑色的狗和1個白色相當於投入到地圖將

map.put("Dog",2); 

我知道它可以使用Stream做,但我不能找出如何。

回答

19

你想要做的是使用name屬性作爲鍵的grouping operation。這是很容易的部分。 Trickier將表示「不同顏色的計數」作爲下游收藏家。由於JRE中沒有這樣的收集器,我們必須利用Set存儲器來構建一個收集器。請注意,即使內置一個,它也不得不在引擎蓋下使用類似的存儲。因此,我們map the elements到顏色,collect them into Sets通過查詢大小(這意味着僅保留不同的值)和finish

Map<String, Integer> map = animalStream.collect(
    Collectors.groupingBy(Animal::getName, 
     Collectors.collectingAndThen(
      Collectors.mapping(Animal::getColor, Collectors.toSet()), 
      Set::size))); 
5

這應該工作:

Map<String, Integer> map = animal.stream().collect(
      Collectors.groupingBy(
        Animal::getName, 
        Collectors.collectingAndThen(
          Collectors.mapping(Animal::getColor, Collectors.toSet()), 
          Set::size) 
        ) 
      ); 

這裏一些測試代碼:

public static void main(String[] args) { 
    List<Animal> animal = new ArrayList<>(); 
    animal.add(new Animal("Dog","black")); 
    animal.add(new Animal("Dog","black")); 
    animal.add(new Animal("Dog","blue")); 
    animal.add(new Animal("Cat","blue")); 
    animal.add(new Animal("Cat","white")); 

    Map<String, Integer> map = animal.stream().collect(
      Collectors.groupingBy(
        Animal::getName, 
        Collectors.collectingAndThen(
          Collectors.mapping(Animal::getColor, Collectors.toSet()), 
          Set::size) 
        ) 
      ); 

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

} 

給出

Cat : 2 
Dog : 2 

注:這個答案的靈感來自於該SO後:https://stackoverflow.com/a/30282943/1138523

+0

你可以,如果你願意,使用地圖::針對的forEach測試代碼:map.forEach((鍵,值) - > System.out中。 println(key +「:」+ value)); – srborlongan

+2

謝謝,不知道 –

相關問題