2016-04-11 34 views
14

Vì vậy, giả sử tôi có một Arraylist của đối tượng Animal. Đó là lớp học của đối tượng là như thế này:Đếm các thuộc tính của các đối tượng trong danh sách bằng cách sử dụng java 8

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

Những gì tôi muốn làm, là đếm có bao nhiêu màu sắc khác nhau tồn tại cho mỗi con vật trong ArrayList và đặt chúng trong một Map<String,Integer> nơi String là Tên và Integer là dành cho số lượng màu sắc khác nhau.

Ví dụ, nếu có 4 con chó màu đen và 1 trắng đặt tương đương với bản đồ sẽ

map.put("Dog",2); 

Tôi biết nó có thể được thực hiện bằng Stream nhưng tôi không thể tìm ra cách.

Trả lời

19

Điều bạn muốn làm là grouping operation sử dụng thuộc tính tên làm khóa. Đó là phần dễ dàng. Trickier là để thể hiện "đếm màu sắc khác biệt" như thu gom hạ lưu. Vì không có trình thu thập như vậy trong JRE, chúng tôi phải tạo một bộ sưu tập, sử dụng bộ nhớ Set. Lưu ý rằng ngay cả khi đã tích hợp sẵn, nó phải sử dụng một bộ nhớ tương tự dưới mui xe. Vì vậy, chúng tôi map the elements đến màu sắc, collect them into Sets (mà ngụ ý chỉ giữ lại giá trị khác biệt) và finish bằng cách truy vấn kích thước:

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

này nên làm việc:

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

Dưới đây một số kiểm tra mã:

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()); 
    } 

} 

cho

Cat : 2 
Dog : 2 

Lưu ý: câu trả lời này được lấy cảm hứng từ bài đăng SO này: https://stackoverflow.com/a/30282943/1138523

+0

Bạn có thể sử dụng Map :: forEach cho mã thử nghiệm: map.forEach ((key, value) -> System.out. println (khóa + ":" + giá trị)); – srborlongan

+2

Cảm ơn, không biết –

Các vấn đề liên quan