Java 流:有关收集到 Map<String、Object> 的问题

2022-09-04 02:06:26

我遇到了一个问题:

我已经创建了这个流,我需要映射到一个:Map<String, Object>

private Map<String, Object> collectArguments(JoinPoint point) {
    CodeSignature signature = (CodeSignature) point.getSignature();
    String[] argNames = signature.getParameterNames();
    Object[] args = point.getArgs();

    return IntStream.range(0, args.length)
        .collect(Collectors.toMap(param -> argNames[param], param -> args[param]));
}

我收到以下消息,我不太清楚:

[Java] Type mismatch: cannot convert from Collector<Object,capture#3-of ?,Map<Object,Object>> to Supplier<R>

答案 1

IntStream没有接受 .它只有一个具有此签名的 3 参数方法:collectCollectorcollect

<R> R collect(Supplier<R> supplier,
              ObjIntConsumer<R> accumulator,
              BiConsumer<R, R> combiner)

也许你应该使用:Stream<Integer>

return IntStream.range(0, args.length)
                .boxed()
                .collect(Collectors.toMap(param -> argNames[param],
                                          param -> args[param]));

或者,如果您希望使用 的方法,它将如下所示:collectIntStream

return IntStream.range(0, args.length)
                .collect(HashMap::new,
                         (m,i)->m.put(argNames[i],args[i]),
                         (m1,m2)->m1.putAll (m2));

return IntStream.range(0, args.length)
                .collect(HashMap::new,
                         (m,i)->m.put(argNames[i],args[i]),
                         Map::putAll);

答案 2

Eran的答案(其中第一个变体,使用a非常整洁)的替代方法是首先将数组的内容映射到对象:Stream<Integer>

public class Argument {
  private final String argName;
  private final Object arg;

  public Argument(String argName, Object arg) {
    this.argName = argName;
    this.arg = arg;
  }

  public String getArgName() {
    return argName;
  }

  public Object getArg() {
    return arg;
  }
}

用于将此对象收集到映射的代码将成为一个非常清晰简洁的基本流:

Map<String, Object> map = IntStream.range(0, args.length)
    .mapToObj(i -> new Argument(argNames[i], args[i]))
    .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));

甚至可以将创建 s 的逻辑提取到自己的方法中:Argument

private List<Argument> toArguments(JoinPoint point) {
  String[] argNames = ((CodeSignature) point.getSignature()).getParameterNames();
  return IntStream.range(0, point.getArgs().length)
      .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
      .collect(Collectors.toList());
}

这样做,您的方法将是一个简单的单行代码:collectArguments()

private Map<String, Object> collectArguments(JoinPoint point) {
  return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
}

推荐