Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过谓词对集合进行分区的库方法_Java_Collections_Guava - Fatal编程技术网

Java 通过谓词对集合进行分区的库方法

Java 通过谓词对集合进行分区的库方法,java,collections,guava,Java,Collections,Guava,我有一个对象集合,我想将其划分为两个集合,其中一个传递谓词,另一个传递谓词。我希望有一个方法可以做到这一点,但最接近的是,这并没有给我其他的收集 我想象这个方法的签名是这样的: public static <E> Pair<Collection<E>, Collection<E>> partition(Collection<E> source, Predicate<? super E> predicate) 公共静态对分区

我有一个对象集合,我想将其划分为两个集合,其中一个传递谓词,另一个传递谓词。我希望有一个方法可以做到这一点,但最接近的是,这并没有给我其他的收集

我想象这个方法的签名是这样的:

public static <E> Pair<Collection<E>, Collection<E>> partition(Collection<E> source, Predicate<? super E> predicate)
公共静态对分区(集合源,谓词使用Guava

下面是一个示例,它将单词列表分为两部分:长度大于3的单词和长度不大于3的单词

List<String> words = Arrays.asList("foo", "bar", "hello", "world");

ImmutableListMultimap<Boolean, String> partitionedMap = Multimaps.index(words, new Function<String, Boolean>(){
    @Override
    public Boolean apply(String input) {
        return input.length() > 3;
    }
});
System.out.println(partitionedMap);
如果您使用的是(以前的GS集合),则可以在所有
RichIterables
上使用
partition
方法

MutableList<Integer> integers = FastList.newListWith(-3, -2, -1, 0, 1, 2, 3);
PartitionMutableList<Integer> result = integers.partition(IntegerPredicates.isEven());
Assert.assertEquals(FastList.newListWith(-2, 0, 2), result.getSelected());
Assert.assertEquals(FastList.newListWith(-3, -1, 1, 3), result.getRejected());
如果您的集合不是一个
RichIterable
,您仍然可以在Eclipse集合中使用静态实用程序

PartitionIterable<Integer> partitionIterable = Iterate.partition(integers, IntegerPredicates.isEven());
PartitionMutableList<Integer> partitionList = ListIterate.partition(integers, IntegerPredicates.isEven());
partitionTable partitionTable=Iterate.partition(integers,IntegerPredicates.isEven());
PartitionMutableList partitionList=ListIterate.partition(integers,IntegerPredicates.isEven());

注意:我是Eclipse集合的提交者。

使用新的java 8功能(和),您可以编写:

PartitionIterable<Integer> partitionIterable = Iterate.partition(integers, IntegerPredicates.isEven());
PartitionMutableList<Integer> partitionList = ListIterate.partition(integers, IntegerPredicates.isEven());
List<String> words = Arrays.asList("foo", "bar", "hello", "world");

Map<Boolean, List<String>> partitionedMap =
        words.stream().collect(
                Collectors.partitioningBy(word -> word.length() > 3));

System.out.println(partitionedMap);
List words=Arrays.asList(“foo”、“bar”、“hello”、“world”);
地图分区地图=
words.stream().collect(
Collectors.partitionby(word->word.length()>3));
System.out.println(分区地图);

提供了基于一个或多个谓词对
Iterable
对象进行分区的方法。(查找
分区(…)
方法。)

请注意,如果预先知道的分区键集有限,则只需针对每个分区键再次迭代集合,跳过每次迭代中的所有不同键项,可能会更有效。因为这样不会为垃圾收集器分配许多新对象

LocalDate start = LocalDate.now().with(TemporalAdjusters.firstDayOfYear());
LocalDate endExclusive = LocalDate.now().plusYears(1);
List<LocalDate> daysCollection = Stream.iterate(start, date -> date.plusDays(1))
        .limit(ChronoUnit.DAYS.between(start, endExclusive))
        .collect(Collectors.toList());
List<DayOfWeek> keys = Arrays.asList(DayOfWeek.values());

for (DayOfWeek key : keys) {
    int count = 0;
    for (LocalDate day : daysCollection) {
        if (key == day.getDayOfWeek()) {
            ++count;
        }
    }
    System.out.println(String.format("%s: %d days in this year", key, count));
}

对于新的Java 12
收集器::teeing
:

var dividedStrings = Stream.of("foo", "hello", "bar", "world")
            .collect(Collectors.teeing(
                    Collectors.filtering(s -> s.length() <= 3, Collectors.toList()),
                    Collectors.filtering(s -> s.length() > 3, Collectors.toList()),
                    List::of
            ));
System.out.println(dividedStrings.get(0)); //[foo, bar]
System.out.println(dividedStrings.get(1)); //[hello, world]
var dividedStrings=Stream.of(“foo”、“hello”、“bar”、“world”)
收集(
Collectors.filtering(s->s.length()s.length()>3,Collectors.toList()),
列表::的
));
System.out.println(dividedStrings.get(0));//[foo,bar]
System.out.println(dividedStrings.get(1));//[hello,world]

你可以找到更多的例子。

谢谢,我没有想到要看那里。如果你已经有了一个谓词,你可以将它转换成一个带有Functions.forPredicate.Update for Java 8的函数:流包
Java.util.stream.Collectors#groupingBy(Java.util.Function.Function)中也提供了类似的方法
类似于
words.stream().collect(collector.groupingBy(func))
@PeterandtheWolf根据您的建议,我添加了一个答案。注意,如果预先知道的分区密钥集有限,只需对每个分区密钥重复一次集合,跳过每次迭代中所有不同的密钥项,GC效率可能会更高。另一种GC友好和封装的方法是我们INGJava8围绕原始集合过滤包装流:有人知道分区函数第一次出现在集合库中的时间/地点吗?
List<AbstractMap.SimpleEntry<DayOfWeek, Stream<LocalDate>>> partitions = keys.stream().map(
        key -> new AbstractMap.SimpleEntry<>(
                key, daysCollection.stream().filter(
                    day -> key == day.getDayOfWeek())))
        .collect(Collectors.toList());
// partitions could be passed somewhere before being used
partitions.forEach(pair -> System.out.println(
        String.format("%s: %d days in this year", pair.getKey(), pair.getValue().count())));
MONDAY: 57 days in this year
TUESDAY: 57 days in this year
WEDNESDAY: 57 days in this year
THURSDAY: 57 days in this year
FRIDAY: 56 days in this year
SATURDAY: 56 days in this year
SUNDAY: 56 days in this year
var dividedStrings = Stream.of("foo", "hello", "bar", "world")
            .collect(Collectors.teeing(
                    Collectors.filtering(s -> s.length() <= 3, Collectors.toList()),
                    Collectors.filtering(s -> s.length() > 3, Collectors.toList()),
                    List::of
            ));
System.out.println(dividedStrings.get(0)); //[foo, bar]
System.out.println(dividedStrings.get(1)); //[hello, world]