JAVA-8流收集高级用法

时间:2015-11-26 09:44:20

标签: java lambda java-8 java-stream collectors

package streams;

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

class Student{
    String name;
    int age;
    String type;

    public Student(){}

    public Student(String name, int age, String type) {
        this.name = name;
        this.age = age;
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", type='" + type + '\'' +
                '}';
    }

    public static List<Student> generateData() {

        List<Student> st = Arrays.asList(new Student("Ashish", 27, "College"),
                new Student("Aman", 24, "School"),
                new Student("Rahul", 18, "School"),
                new Student("Ajay", 29, "College"),
                new Student("Mathur", 25, "College"),
                new Student("Modi", 28, "College"),
                new Student("Prem", 15, "School"),
                new Student("Akash", 17, "School"));
        return st;
    }
}
//AdvancedStreamingP2 class uses the Student class

package streams;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.*;

public class AdvancedStreamingP2 {

    public static void main(String[] args) {

        List<Student> studentList = Student.generateData();
        System.out.println("\n---------- Extracting Student Name with Max Age by Type -----------");
        Map<String, Optional<Student>> stuMax = studentList.stream().collect(groupingBy(Student::getType, maxBy(comparing(Student::getAge))));
        stuMax.forEach((k, v) -> System.out.println("Key : " + k + ", Value :" + v.get()));
    }
}

我想提取具有最大年龄的学生姓名,按类型对学生进行分组。是否可以在“收集”中使用任何组合?

我希望输出如下:

---------- Extracting Student Name with Max Age by Type -----------

Key : School, Value : Aman
Key : College, Value : Ajay

3 个答案:

答案 0 :(得分:8)

是的,您可以使用Collectors.collectingAndThen。此收集器调整现有收集器以执行其他修整器操作。在这种情况下,修整器操作只返回学生的名称。

protocol Controller2Delegate {
  func controller2DidReturn()
}

class Controller1: Controller2Delegate {
  func controller2DidReturn() {
    // your code.
  }

  func prepareForSegue(...) {
    // get controller2 instance

    controller2.delegate = self
  }
}

class Controller2 {
  var delegate: Controller2Delegate!

  func done() {
    // dismiss viewcontroller

    delegate.controller2DidReturn()
  }
}

输出:

Map<String, String> stuMax = 
    studentList.stream()
               .collect(groupingBy(
                    Student::getType, 
                    collectingAndThen(maxBy(comparing(Student::getAge)), v -> v.get().getName()) 
               ));

旁注:您可以使用comparingInt而非使用---------- Extracting Student Name with Max Age by Type ----------- Key : School, Value :Aman Key : College, Value :Ajay ,因为comparing会返回Person.getAge():这可以避免不必要的装箱。

答案 1 :(得分:0)

Checkout below advanc java 8中的Consumer示例: -

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class Java8ConsumerExample1 {
private static List<Integer> QUERY_RESULTSET_INTEGER = Arrays.asList(new   Integer(1), new Integer(10), new Integer(200), new Integer(101), new Integer(-10), new Integer(0));
private static List<String> QUERY_RESULTSET_STRING = Stream.of("A", "B", "C", "D", "E", "F").collect(Collectors.toList());

public static void main(String[] args) {

    // EXAMPLE : 1

    /**
     * Iterator over the Query generated integer list and print on console.
     */
    StubsUtils.forEach(new ExecutorContext() {
        List<Integer> consumerList = new ArrayList<Integer>();

        /**
         * Let's assume that our query returns set of Integer that would be consume by some caller class or print on console.
         * @return
         */
        @Override
        public List<Integer> getQuery() {
            return QUERY_RESULTSET_INTEGER;
        }

        @Override
        public Consumer<Integer> getConsumer() {
            return x -> {
                System.out.println(x);
                consumerList.add(x);
            };
        }
    });

    // EXAMPLE : 2
    /**
     * Iterator over the Query generated String list and print on console.
     */
    StubsUtils.forEach(new ExecutorContext() {
        List<String> consumerList = new ArrayList<String>();

        /**
         * Let's assume that our query returns set of Integer that would be consume by some caller class or print on console.
         * @return
         */
        @Override
        public List<String> getQuery() {
            return QUERY_RESULTSET_STRING;
        }

        @Override
        public Consumer<String> getConsumer() {
            return x -> {
                System.out.println(x);
                consumerList.add(x);
            };
        }
    });

}
}

StubsUtils.Java

 /**
   * Utility class
 */
 class StubsUtils {

 public static void forEach(ExecutorContext executorContext) {
    executorContext.getQuery().forEach(executorContext.getConsumer());
}

}

ExecutorContext.Java

interface ExecutorContext<E> {

List<Integer> getQuery();

Consumer<E> getConsumer();
}

答案 2 :(得分:0)

这是另一个消费者示例: -

MMddyyy