当前位置: 首页 > news >正文

Stream流与Lambda表达式(三) 静态工厂类Collectors

/**
 * @author 陈杨
 */

@SpringBootTest
@RunWith(SpringRunner.class)
public class CollectorsDetail {

    private List<String> names;
    private List<Student> students;
    private List<List<String>> snames;

    @Before
    public void init() {

        names = Arrays.asList("Kirito", "Asuna", "Sinon", "Yuuki", "Alice");
        snames = Arrays.asList(Collections.singletonList("Kirito"), Collections.singletonList("Asuna"),
                Collections.singletonList("Sinon"), Collections.singletonList("Yuuki"),
                Collections.singletonList("Alice"));

        students = new Students().init();
    }

    @Test
    public void testCollectorsDetail() {

一、静态工厂类Collectors 实现方式

//    一、静态工厂类Collectors 实现方式

//    Collectors 静态工厂类   最终由CollectorImpl实现
//       1、 通过CollectorImpl实现
//       2、 通过reducing()实现---> reducing()底层由CollectorImpl实现


//    Collectors.toList()  是 Collectors.toCollection()的一种具化表现形式
//    Collectors.joining() 使用StringBuilder.append 拼接字符串

二、静态工厂类Collectors 常用收集器

//    二、静态工厂类Collectors 常用收集器

/*
      返回一个(不可修改)unmodifiable List的ArrayList  按照相遇的顺序encounter order
@since 10
@SuppressWarnings("unchecked")
public static <T>
        Collector<T, ?, List<T>> toUnmodifiableList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
            (left, right) -> { left.addAll(right); return left; },
            list -> (List<T>)List.of(list.toArray()),
            CH_NOID);
}*/


/*
      返回一个(不可修改)unmodifiable Set的HashSet 无序
@since 10
@SuppressWarnings("unchecked")
public static <T>
        Collector<T, ?, Set<T>> toUnmodifiableSet() {
    return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
            (left, right) -> {
                if (left.size() < right.size()) {
                    right.addAll(left); return right;
                } else {
                    left.addAll(right); return left;
                }
            },
            set -> (Set<T>)Set.of(set.toArray()),
            CH_UNORDERED_NOID);
}
*/


/*
      返回一个flatMapping扁平化mapper处理后 由downstream收集的 累加器处理的结果合并  单线程
@since 9
public static <T, U, A, R>
        Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
        Collector<? super U, A, R> downstream) {
    BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
    return new CollectorImpl<>(downstream.supplier(),
            (r, t) -> {
                try (Stream<? extends U> result = mapper.apply(t)) {
                    if (result != null)
                        result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
                }
            },
            downstream.combiner(), downstream.finisher(),
            downstream.characteristics());
}*/



/*
      对符合Predicate预期结果 进行过滤filtering 使用downstream 收集元素
@since 9
public static <T, A, R>
        Collector<T, ?, R> filtering(Predicate<? super T> predicate,
        Collector<? super T, A, R> downstream) {
    BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
    return new CollectorImpl<>(downstream.supplier(),
            (r, t) -> {
                if (predicate.test(t)) {
                    downstreamAccumulator.accept(r, t);
                }
            },
            downstream.combiner(), downstream.finisher(),
            downstream.characteristics());
}*/


/*
      使用Map映射key-->keyMapper-->Key value-->valueMapper-->Value
      对映射后的结果进行组装entrySet-->Map<Key,Value> (unmodifiable Map)
@since 10
@SuppressWarnings({"rawtypes", "unchecked"})
public static <T, K, U>
        Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
        Function<? super T, ? extends U> valueMapper) {
    Objects.requireNonNull(keyMapper, "keyMapper");
    Objects.requireNonNull(valueMapper, "valueMapper");
    return collectingAndThen(
            toMap(keyMapper, valueMapper),
            map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
}*/


/*
      使用Map映射key-->keyMapper-->Key value-->valueMapper-->Value
      mergeFunction 对相同key 映射后的进行Value 合并操作
      对映射后的结果进行组装entrySet-->Map<Key,Value> (unmodifiable Map)

@since 10
@SuppressWarnings({"rawtypes", "unchecked"})
public static <T, K, U>
        Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
        Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction) {
    Objects.requireNonNull(keyMapper, "keyMapper");
    Objects.requireNonNull(valueMapper, "valueMapper");
    Objects.requireNonNull(mergeFunction, "mergeFunction");
    return collectingAndThen(
            toMap(keyMapper, valueMapper, mergeFunction, HashMap::new),
            map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
}*/
//    Collectors 收集器
System.out.println("-----------------------------------------\n");

//    使用ArrayList集合 按照流中元素排列先后顺序 进行添加操作
List<String> unmodifiableList = names.stream().collect(Collectors.toUnmodifiableList());
System.out.println(unmodifiableList);
System.out.println("---------------------------------------\n");


//    使用HashSet集合 对流中元素顺序 进行添加操作
Set<String> unmodifiableSet = names.stream().collect(Collectors.toUnmodifiableSet());
System.out.println(unmodifiableSet);
System.out.println("---------------------------------------\n");


//    将集合扁平化展开 对其中的字符串的每个字母 进行大写转换 使用ArrayList对转换后的结果进行收集
List<String> strings = snames.stream()
        .collect(Collectors.flatMapping(list -> list.stream().map(String::toUpperCase), Collectors.toList()));
System.out.println(strings);
System.out.println("---------------------------------------\n");


//    对流中元素进行遍历 对符合预期要求的元素 使用ArrayList集合存放
List<String> filteringPredicate = names.stream().collect(Collectors.filtering("Kirito"::equals,
        Collectors.toList()));
System.out.println(filteringPredicate);
System.out.println("---------------------------------------\n");


//    对流中元素进行遍历  对key-->keyMapper value-->valueMapper 映射 得到Map集合
Map<Integer, List<Student>> listMap = students.stream()
        .collect(Collectors.toUnmodifiableMap(Student::getId, student -> {
            List<Student> stus = new ArrayList<>();
            stus.add(student);
            return stus;
        }));

System.out.println(listMap);
System.out.println("---------------------------------------\n");


//    对流中元素进行遍历 对key-->keyMapper-->Key value-->valueMapper-->Value 映射
//    对满足相同Key的元素 Value进行合并
Map<Integer, String> lengthName = names.stream()
        .collect(Collectors.toUnmodifiableMap(String::length,
                String::toString, (str1, str2) -> str1 + "\t" + str2));
System.out.println(lengthName);
System.out.println("---------------------------------------\n");

三、groupingBy分组

//    三、groupingBy分组

//    分组 groupingBy

//    对T元素按 key进行分组 --> 分组的依据 classifier--> 分组后的集合 value--> 得到 Map<key,value>
/*
Returns a {@code Collector} implementing a "group by" operation on
input elements of type {@code T}, grouping elements according to a
         classification function, and returning the results in a {@code Map}.

<p>The classification function maps elements to some key type {@code K}.
The collector produces a {@code Map<K, List<T>>} whose keys are the
values resulting from applying the classification function to the input
elements, and whose corresponding values are {@code List}s containing the
         input elements which map to the associated key under the classification
function.

<p>There are no guarantees on the type, mutability, serializability, or
thread-safety of the {@code Map} or {@code List} objects returned.*/


/*
      按照key对T进行classifier分组
      使用List集合收集分组结果  单线程 线程安全
public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier) {
    return groupingBy(classifier, toList());
}*/


/*
      按照key对T进行classifier分组
      使用自定义收集器downstream 收集分组结果  单线程 线程安全
public static <T, K, A, D>
        Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
        Collector<? super T, A, D> downstream) {
    return groupingBy(classifier, HashMap::new, downstream);
}*/


/*
      按照key对T进行classifier分组
      使用自定义mapFactory  重置downstream的CollectorImpl实现
      使用自定义收集器downstream 收集分组结果  单线程 线程安全
public static <T, K, D, A, M extends Map<K, D>>
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
        Supplier<M> mapFactory,
        Collector<? super T, A, D> downstream) {
    Supplier<A> downstreamSupplier = downstream.supplier();
    BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
    BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
        K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
        A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
        downstreamAccumulator.accept(container, t);
    };
    BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
    @SuppressWarnings("unchecked")
    Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
    //    不进行强制类型转换  重构CollectorImpl实现
    if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
        return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
    }
    else {
        //    进行强制类型转换  重构CollectorImpl实现
        @SuppressWarnings("unchecked")
        Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
        Function<Map<K, A>, M> finisher = intermediate -> {
            intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
            @SuppressWarnings("unchecked")
            M castResult = (M) intermediate;
            return castResult;
        };
        return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
    }
}*/
//    分组
System.out.println("-----------------------------------------\n");


//    select * from students group by sex ;
Map<String, List<Student>> sexStudent =
        students.stream().collect(Collectors.groupingBy(Student::getSex));
System.out.println(sexStudent);
System.out.println("-----------------------------------------\n");


//    select sex, count(*) from students group by sex ;
Map<String, Long> sexCount =
        students.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.counting()));
System.out.println(sexCount);
System.out.println("-----------------------------------------\n");


//    select sex,avg(salary) from students group by sex ;
Map<String, Double> avgSexSalary = students.stream().collect
        (Collectors.groupingBy(Student::getSex, Collectors.averagingDouble(Student::getSalary)));
System.out.println(avgSexSalary);
System.out.println("-----------------------------------------\n");


//    嵌套分组  先根据sex分组 再对结果按照addr进行分组
Map<String, Map<String, List<Student>>> NestedGroupBy = students.stream()
        .collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAddr)));
System.out.println(NestedGroupBy);
System.out.println("-----------------------------------------\n");


//    使用自定义收集器downstream 按性别分组  使用HashSet进行 结果收集
Map<String, HashSet<Student>> sexHashSet = students.stream()
        .collect(Collectors.groupingBy(Student::getSex, Collectors.toCollection(HashSet::new)));
System.out.println(sexHashSet);
System.out.println("-----------------------------------------\n");


//    使用自定义收集器downstream 按性别分组  使用HashSet进行 结果收集  重置CollectorImpl实现
Map<String, HashSet<Student>> sexCustomCollectorImpl = students.stream()
        .collect(Collectors.groupingBy(Student::getSex, Hashtable::new, Collectors.toCollection(HashSet::new)));
System.out.println(sexCustomCollectorImpl);
System.out.println("-----------------------------------------\n");

四、groupingByConcurrent分组

 //    四、groupingByConcurrent分组

 //    分组 groupingByConcurrent

 //    流的适用条件:
 //          无序 Collector.Characteristics.UNORDERED
 //          并发 Collector.Characteristics.CONCURRENT
 //    This is a {@link Collector.Characteristics#CONCURRENT concurrent} and
 //    {@link Collector.Characteristics#UNORDERED unordered} Collector.


 /*
       按照key对T进行classifier分组
       使用List集合收集分组结果
 public static <T, K>
         Collector<T, ?, ConcurrentMap<K, List<T>>>
 groupingByConcurrent(Function<? super T, ? extends K> classifier) {
     return groupingByConcurrent(classifier,  ::new, toList());
 }*/


/*
       按照key对T进行classifier分组
       使用自定义收集器downstream 收集分组结果
public static <T, K, A, D>
         Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier,
         Collector<? super T, A, D> downstream) {
     return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream);
 }*/


 /*
       按照key对T进行classifier分组
       使用自定义累加器mapFactory  重置downstream的CollectorImpl实现
       使用自定义收集器downstream 收集分组结果
 public static <T, K, A, D, M extends ConcurrentMap<K, D>>
 Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier,
         Supplier<M> mapFactory,
         Collector<? super T, A, D> downstream) {
     Supplier<A> downstreamSupplier = downstream.supplier();
     BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
     BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner());
     @SuppressWarnings("unchecked")
     Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory;
     BiConsumer<ConcurrentMap<K, A>, T> accumulator;
     if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) {
         accumulator = (m, t) -> {
             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
             A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
             downstreamAccumulator.accept(resultContainer, t);
         };
     }
     else {
         accumulator = (m, t) -> {
             K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
             A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get());
             //  多个操作-->同时操作同一个结果容器-->同一时间,有且只有一个进行实际操作-->线程同步
             synchronized (resultContainer) {
                 downstreamAccumulator.accept(resultContainer, t);
             }
         };
     }

     if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
         return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID);
     }
     else {
         @SuppressWarnings("unchecked")
         Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
         Function<ConcurrentMap<K, A>, M> finisher = intermediate -> {
             intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
             @SuppressWarnings("unchecked")
             M castResult = (M) intermediate;
             return castResult;
         };
         return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID);
     }
 }*/
//    分组 无序 并发
System.out.println("-----------------------------------------\n");

//    按性别分组  使用ArrayList进行 结果收集
ConcurrentMap<String, List<Student>> sexStudentConcurrent = students.stream()
        .collect(Collectors.groupingByConcurrent(Student::getSex));
System.out.println(sexStudentConcurrent);
System.out.println("-----------------------------------------\n");


//    使用自定义收集器downstream 按性别分组  使用HashSet进行 结果收集
ConcurrentMap<String, HashSet<Student>> sexHashSetConcurrent = students.stream()
        .collect(Collectors.groupingByConcurrent(Student::getSex, Collectors.toCollection(HashSet::new)));
System.out.println(sexHashSetConcurrent);
System.out.println("-----------------------------------------\n");


//    使用自定义收集器downstream 按性别分组  使用HashSet进行 结果收集  重置CollectorImpl实现
ConcurrentReferenceHashMap<String, HashSet<Student>> sexCustomCollectorImplConcurrent =
        students.stream().collect(Collectors.groupingByConcurrent(Student::getSex,
                ConcurrentReferenceHashMap::new, Collectors.toCollection(HashSet::new)));
System.out.println(sexCustomCollectorImplConcurrent);
System.out.println("-----------------------------------------\n");

五、partitioningBy分区

//    五、partitioningBy分区

//  分区  partitioningBy

/*
      对满足预期的条件 进行分区 使用ArrayList 进行结果的收集
public static <T>
        Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
    return partitioningBy(predicate, toList());
}*/


/*
      对满足预期的条件 进行分区 使用自定义收集器downstream 进行结果的收集
public static <T, D, A>
        Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
        Collector<? super T, A, D> downstream) {
    BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
    BiConsumer<Partition<A>, T> accumulator = (result, t) ->
            downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
    BinaryOperator<A> op = downstream.combiner();
    BinaryOperator<Partition<A>> merger = (left, right) ->
            new Partition<>(op.apply(left.forTrue, right.forTrue),
                    op.apply(left.forFalse, right.forFalse));
    Supplier<Partition<A>> supplier = () ->
            new Partition<>(downstream.supplier().get(),
                    downstream.supplier().get());
    if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
        return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
    }
    else {
        Function<Partition<A>, Map<Boolean, D>> finisher = par ->
                new Partition<>(downstream.finisher().apply(par.forTrue),
                        downstream.finisher().apply(par.forFalse));
        return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
    }
}*/
        //    分区
        System.out.println("-----------------------------------------\n");

        //    select * from students partition by (addr == Sword Art Online) ;
        Map<Boolean, List<Student>> addrPartition = students.stream().collect
                (Collectors.partitioningBy(student -> student.getAddr().equals("Sword Art Online")));
        System.out.println(addrPartition);
        System.out.println("-----------------------------------------\n");


        //    嵌套分区  先根据sex分区 再对结果按照addr进行分区
        Map<Boolean, Map<Boolean, List<Student>>> NestedPartiton = students.stream()
                .collect(Collectors.partitioningBy(student -> student.getSex().equals("Male"),
                        Collectors.partitioningBy(student -> student.getAddr().equals("Sword Art Online"))));
        System.out.println(NestedPartiton);
        System.out.println("-----------------------------------------\n");


        //    使用自定义downstream收集器分区
        Map<Boolean, HashSet<Student>> addrCustomPartition = students.stream().collect(Collectors.partitioningBy
                (student -> student.getAddr().equals("Sword Art Online"), Collectors.toCollection(HashSet::new)));
        System.out.println(addrCustomPartition);
        System.out.println("-----------------------------------------\n");

    }

}

六、测试结果

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-20 16:58:15.870  INFO 13392 --- [           main] c.j.d.java8.Stream.CollectorsDetail      : Starting CollectorsDetail on DESKTOP-87RMBG4 with PID 13392 (started by 46250 in E:\IdeaProjects\design)
2019-02-20 16:58:15.871  INFO 13392 --- [           main] c.j.d.java8.Stream.CollectorsDetail      : No active profile set, falling back to default profiles: default
2019-02-20 16:58:16.383  INFO 13392 --- [           main] c.j.d.java8.Stream.CollectorsDetail      : Started CollectorsDetail in 0.708 seconds (JVM running for 1.421)
-----------------------------------------

[Kirito, Asuna, Sinon, Yuuki, Alice]
---------------------------------------

[Yuuki, Asuna, Kirito, Sinon, Alice]
---------------------------------------

[KIRITO, ASUNA, SINON, YUUKI, ALICE]
---------------------------------------

[Kirito]
---------------------------------------

{5=[Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], 4=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8)], 3=[Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8)], 2=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)], 1=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
---------------------------------------

{6=Kirito, 5=Asuna    Sinon    Yuuki    Alice}
---------------------------------------

-----------------------------------------

{Female=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

{Female=4, Male=1}
-----------------------------------------

{Female=9.99999999E8, Male=9.99999999E8}
-----------------------------------------

{Female={Alicization=[Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], Sword Art Online=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)], Gun Gale Online=[Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8)], Alfheim Online=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8)]}, Male={Sword Art Online=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}}
-----------------------------------------

{Female=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)], Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

{Female=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)], Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

-----------------------------------------

{Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)], Female=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)]}
-----------------------------------------

{Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)], Female=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

{Female=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)], Male=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

-----------------------------------------

{false=[Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], true=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8), Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

{false={false=[Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], true=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8)]}, true={false=[], true=[Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}}
-----------------------------------------

{false=[Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8), Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8), Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)], true=[Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)]}
-----------------------------------------

相关文章:

  • 自己写代码生成器 (一)
  • Redis的resp协议
  • 炒冷饭系列:设计模式 工厂方法模式
  • 2019年寒假作业2 - 7-1 币值转换
  • JavaScript-如何实现克隆(clone)函数
  • [总结]Android系统体系结构
  • 给第三方使用接口的 URL 签名实现
  • JVM【第四回】:【对象访问】
  • Flask 教程 第一章:Hello, World!
  • Netty源码解析1-Buffer
  • SCCM 2012 R2实战系列之一:SQL安装
  • 【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)
  • ahjesus 让我的MVC web API支持JsonP跨域
  • 《剑指offer》分解让复杂问题更简单
  • 文件编码
  • ----------
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Apache Spark Streaming 使用实例
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • CSS居中完全指南——构建CSS居中决策树
  • Node项目之评分系统(二)- 数据库设计
  • Webpack 4x 之路 ( 四 )
  • 搞机器学习要哪些技能
  • 计算机在识别图像时“看到”了什么?
  • 区块链技术特点之去中心化特性
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 实现菜单下拉伸展折叠效果demo
  • 与 ConTeXt MkIV 官方文档的接驳
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ![CDATA[ ]] 是什么东东
  • (6)STL算法之转换
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (五)关系数据库标准语言SQL
  • (一)SpringBoot3---尚硅谷总结
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)mysql使用Navicat 导出和导入数据库
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • . Flume面试题
  • .dwp和.webpart的区别
  • .Net IE10 _doPostBack 未定义
  • .NET 的程序集加载上下文
  • .NET 反射 Reflect
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .php文件都打不开,打不开php文件怎么办
  • @Conditional注解详解
  • @test注解_Spring 自定义注解你了解过吗?
  • [ 数据结构 - C++] AVL树原理及实现
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [3300万人的聊天室] 作为产品的上游公司该如何?
  • [BZOJ2208][Jsoi2010]连通数
  • [C#] 基于 yield 语句的迭代器逻辑懒执行
  • [c]扫雷
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解