@Override TreeSet 添加方法,用于添加 4 个元素(在 Java 上)

@Override TreeSet add methode for add juste 4 elements (on Java)

我有一个列表,我将它流式传输到一个带有键和值的树图中,其中值是一个 TreeSet 对于这个 TreeSet 我只是将 4 个第一个元素添加到 Treeset 流而不是所有元素

Map<Integer, Set<Person>> stream_exo = ListOfPerson.stream()
                .collect(
                        Collectors.groupingBy(
                                p -> p.getYear(), 
                                TreeMap::new, Collectors.toCollection(TreeSet2::New)));

这里是 java 的树集 Class :

public class TreeSet<E> extends AbstractSet<E>
                   implements NavigableSet<E>, Cloneable, java.io.Serializable {

    private static final Object PRESENT = new Object();
    
    private transient TreeMap<E,Object> internalMap;
    
    public boolean add(E e) {
        return this.internalMap.put(e, PRESENT)==null;
    }
}

我想为 TreeSet 设置函数(添加)以仅向 TreeSet 添加 4 个元素,有人可以问我我们该怎么做吗?

这与流无关...只是简单的继承。

创建一个新的 class“MaxFourTreeSet”,它“扩展了 TreeSet”并覆盖 add() 函数以添加您的条件。然后,在您的信息流中使用 MaxFourTreeSet::new 而不是 TreeSet::new。就这些了。

public class MaxFourTreeSet<E> extends TreeSet<E> {

@Override
public boolean add(E e) {
    if (this.size() <= 4) {
        return super.add(e);
    } 
    return false;
 } 
}

(代码不准确)

第一个

要使用 TreeSet“有序集”),值 (<V>) 必须实现 Comparable<V> 我们必须在TreeSet构造时提供Comparator<Person>

第二

检查这个(如果我们做对了问题):

package com.example;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toSet;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        // test data:
        List<Person> list = List.of(new Person(1969), new Person(1969), new Person(1969), new Person(1969),
            new Person(1969), // 5
            new Person(1971), new Person(1971), new Person(1971), new Person(1971),
            new Person(1971), // 5
            new Person(1999), new Person(1999) // 2
        );
        // action:
        Map<Integer, Set<Person>> stream_exo = list.stream()
            .collect( //..as we had
                groupingBy( // ...
                    p -> p.year, // ... key - function
                    collectingAndThen( // value - "downstream"
                        toSet(), // collector - function (downstream)
                        s ->  s // (and then) set - (finalizer) fuction
                            .stream() //  stream once more ;(, unfortunately i found no nicer way
                            .limit(4) // limit to 4, and finally:
                            .collect(  // ...collect
                                toSet()  // to set TreeSet::new, when Person is Comparable<Person>
                            )
                    ) // end-collectingAndThen
                ) // end-groupingBy
            ); // end-collect
        // output verification:
        stream_exo.forEach((k, v) -> {
            System.out.format("%s:\t%d%n", "key", k);
            v.forEach(p -> System.out.println(p));
        });

    }
}

class Person {
    final int year;

    Person(int pYear) {
        year = pYear;
    }
}

输出:

key:    1969
com.example.Person@31befd9f
com.example.Person@1c20c684
com.example.Person@2f2c9b19
com.example.Person@13221655
key:    1971
com.example.Person@3e3abc88
com.example.Person@1218025c
com.example.Person@548c4f57
com.example.Person@816f27d
key:    1999
com.example.Person@53d8d10a
com.example.Person@6ce253f1

所以 collectingAndThen(再次 stream()limit(),再次 collect())是我对该特定要求的回答!


第三

如果我们想使用 TreeSet,我们必须实现提到的(第一个)接口,“...最后”:

collect(toSet(TreeSet::new)))));

终于

真的一个TreeMap:

TreeMap<Integer, Set<Person>> stream_exo = list.stream()
   ....

我们需要:

...
groupingBy(
    p -> p.year, 
    TreeMap::new, // do additonally this!
    collectingAndThen( ...

还嵌套了TreeSets(没有修改Person,基于person.year),就是这样:

TreeMap<Integer, Set<Person>> stream_exo = list // TreeMap result (Integer IS Comparable<Integer>;)
    .stream()
    .collect(
        groupingBy(
            p -> p.year,
            TreeMap::new,
            collectingAndThen(
                toSet(), // if we want the "intermediary" set also as TreeSet(ordered!), then here!
                s -> 
                    s.stream()
                    .limit(4)
                    .collect(
                        toCollection(() -> {  // TreeSet leafs:
                            return new TreeSet<> ( // with inline comparator
                                (p1, p2) -> Integer.compare(p1.year, p2.year));
                        }
                    )
            )
        )
    );   

...但是 yearComparable<Person> 在这里没用,因为 year 已经 grouped/unique.;)