首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在比赛结束后使用流找到一个项目?

如何在比赛结束后使用流找到一个项目?
EN

Stack Overflow用户
提问于 2015-08-03 13:58:39
回答 8查看 8.6K关注 0票数 9

使用Java流,很容易找到与给定属性匹配的元素。

例如:

代码语言:javascript
运行
复制
 String b = Stream.of("a1","b2","c3")
     .filter(s -> s.matches("b.*"))
     .findFirst().get();
 System.out.println("b = " + b);

生产:

b=b2

然而,人们通常希望在匹配之后得到一个或多个值,而不是匹配本身。我只知道如何用旧的循环方式来做这件事。

代码语言:javascript
运行
复制
    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);

它将产生:

result=2

是否有一种使用Java 8流的干净方法?例如,给定上面的数组和谓词s -> s.matches("-b.*"),将结果设置为"2“。

如果您可以获得下一个值,也可以获得下一个N值或所有值的列表/数组,直到匹配另一个谓词(如s -> s.matches("-c.*") )为止。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2015-08-03 19:48:06

这是用流解决这个问题所需要的分配器:

代码语言:javascript
运行
复制
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; }
  }
}

一旦你把这个藏在项目的某个地方,你可以说

代码语言:javascript
运行
复制
partition(Stream.of("-a","1","-b","2","-c","3"), 2)
      .filter(pair -> pair.get(0).equals("-b"))
      .findFirst()
      .map(pair -> pair.get(1))
      .orElse("");

另外,本文提出的分集器依赖于trySplitAbstractSpliterator中的默认实现来支持并行性。

票数 4
EN

Stack Overflow用户

发布于 2015-08-03 15:22:26

我是通过这篇博文找到的:

https://blog.jooq.org/when-the-java-8-streams-api-is-not-enough/

名为jOOL的库有一个Github链接。

https://github.com/jOOQ/jOOL

和Maven central Info在这里:

http://mvnrepository.com/artifact/org.jooq/jool/0.9.6

该示例的代码如下:

代码语言:javascript
运行
复制
import org.jooq.lambda.Seq;

..。

代码语言:javascript
运行
复制
    String result = Seq.of(args)
            .skipWhile(s -> !s.matches("-b.*"))
            .skip(1)
            .findFirst()
            .get();
票数 4
EN

Stack Overflow用户

发布于 2015-08-03 15:10:29

我不能说以下内容是有效的,但它遵循一个易于应用的模式。(然而,在实际的函数式语言中,添加过滤器时,它可能是有效的。)

首先从字符串流收集[[-c, 3], [-b, 2], [-a, 1]]

代码语言:javascript
运行
复制
    List<List<String>> optionLists = Stream.of("-a","1","-b","2","-c","3")
            .collect(ArrayList<List<String>>::new,
                    (lists, arg) -> {
                        if (arg.startsWith("-")) {
                            List<String> list = new LinkedList<>();
                            list.add(arg);
                            lists.add(0, list);
                        } else {
                            List<String> list = lists.get(0);
                            list.add(arg);
                        }
                    },
                    List::addAll);
    System.out.println(optionLists);

然后,人们可能会把它交给一个地图,为所有的选项。

代码语言:javascript
运行
复制
    List<String> bargs = optionLists.stream()
            .collect(Collectors.toMap(lst -> lst.get(0),
                    lst -> lst.subList(1, lst.size()))).get("-b");
    System.out.println("For -b: " + bargs);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31789279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档