使用Java流,很容易找到与给定属性匹配的元素.
如:
String b = Stream.of("a1","b2","c3")
.filter(s -> s.matches("b.*"))
.findFirst().get();
System.out.println("b = " + b);
Run Code Online (Sandbox Code Playgroud)
产生:
b = b2
然而,通常人们在匹配后想要一个或多个值,而不是匹配本身.我只知道如何用旧时尚循环来做到这一点.
String args[] = {"-a","1","-b","2","-c","3"};
String result = "";
for (int i = 0; i < args.length-1; i++) {
String arg = args[i];
if(arg.matches("-b.*")) {
result= args[i+1];
break;
}
}
System.out.println("result = " + result);
Run Code Online (Sandbox Code Playgroud)
哪个会产生:
结果= 2
使用Java 8 Streams有一种干净的方法吗?例如,给定上面的数组和谓词,将结果设置为"2" s -> s.matches("-b.*").
如果你可以获得下一个值,那么也可以获得下一个N值或所有值的列表/数组,直到另一个谓词匹配为止s -> s.matches("-c.*").
这是用流解决这个问题所需的分离器:
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators.AbstractSpliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class PartitioningSpliterator<E> extends AbstractSpliterator<List<E>>
{
private final Spliterator<E> spliterator;
private final int partitionSize;
public PartitioningSpliterator(Spliterator<E> toWrap, int partitionSize) {
super(toWrap.estimateSize(), toWrap.characteristics());
if (partitionSize <= 0) throw new IllegalArgumentException(
"Partition size must be positive, but was " + partitionSize);
this.spliterator = toWrap;
this.partitionSize = partitionSize;
}
public static <E> Stream<List<E>> partition(Stream<E> in, int size) {
return StreamSupport.stream(new PartitioningSpliterator(in.spliterator(), size), false);
}
@Override public boolean tryAdvance(Consumer<? super List<E>> action) {
final HoldingConsumer<E> holder = new HoldingConsumer<>();
if (!spliterator.tryAdvance(holder)) return false;
final ArrayList<E> partition = new ArrayList<>(partitionSize);
int j = 0;
do partition.add(holder.value); while (++j < partitionSize && spliterator.tryAdvance(holder));
action.accept(partition);
return true;
}
@Override public long estimateSize() {
final long est = spliterator.estimateSize();
return est == Long.MAX_VALUE? est
: est / partitionSize + (est % partitionSize > 0? 1 : 0);
}
static final class HoldingConsumer<T> implements Consumer<T> {
T value;
@Override public void accept(T value) { this.value = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你把它藏在项目的某个地方,你就可以说
partition(Stream.of("-a","1","-b","2","-c","3"), 2)
.filter(pair -> pair.get(0).equals("-b"))
.findFirst()
.map(pair -> pair.get(1))
.orElse("");
Run Code Online (Sandbox Code Playgroud)
顺便说一句,所提出的 spliterator 通过依赖trySplitin的默认实现来支持并行性AbstractSpliterator。
| 归档时间: |
|
| 查看次数: |
2778 次 |
| 最近记录: |