当前位置: 首页 > 知识库问答 >
问题:

Java8个流中介映射/收集到一个有2个值的流

司寇经亘
2023-03-14

假设我有以下工作的lambda表达式:

        Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
            .filter(f -> f.isAnnotationPresent(Column.class))
            .collect(toMap(f -> {
                f.setAccessible(true);
                return f;
            }, f -> f.getAnnotation(Column.class).name()));

我想在过滤器语句之前创建一个具有2个值的流。所以我想做一个映射,但仍然保留原始值。我想实现这样的事情:

        this.fields = Arrays.stream(resultClass.getDeclaredFields())
            //map to <Field, Annotation> stream
            .filter((f, a) -> a != null)
            .collect(toMap(f -> {
                f.setAccessible(true);
                return f;
            }, f -> a.name()));

这可能与Java8流?我已经看了收集(GroupingBy()),但仍然没有成功。

共有3个答案

苍兴怀
2023-03-14

@彼得·劳里:我用一张地图试过你的建议。它现在可以用了,但并不漂亮。

this.fields = Arrays.stream(resultClass.getDeclaredFields())
            .collect(HashMap<Field, Column>::new, (map, f) -> map.put(f, f.getAnnotation(Column.class)), HashMap::putAll)
            .entrySet().stream()
            .filter(entry -> entry.getValue() != null)
            .peek(entry -> entry.getKey().setAccessible(true))
            .collect(toMap(Map.Entry::getKey, entry -> entry.getValue().name()));
邹英悟
2023-03-14

collect操作期间,您可以一次性完成整个操作,而无需配对类型:

Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
    .collect(HashMap::new, (m,f) -> {
        Column c=f.getAnnotation(Column.class);
        if(c!=null) {
            f.setAccessible(true);
            m.put(f, c.name());
        }
    }, Map::putAll);

尽管如此,在我看来,将两个不在一起的操作分开似乎更干净:

Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
    .collect(HashMap::new, (m,f) -> {
        Column c=f.getAnnotation(Column.class);
        if(c!=null) m.put(f,c.name());
    }, Map::putAll);

AccessibleObject.setAccessible(
    fields.keySet().stream().toArray(AccessibleObject[]::new), true);

该解决方案确实会在具有注释的字段上迭代两次,但由于它只对每个字段执行一次安全检查,而不是一次检查,因此它可能仍然优于所有其他解决方案。

一般来说,除非确实存在性能问题,否则您不应该尝试优化,如果您这样做了,您应该测量,而不是猜测操作的成本。结果可能令人惊讶,在一个数据集上多次迭代不一定是坏的。

孔欣可
2023-03-14

你需要一个像对这样的东西,它包含两个值。您可以自己编写,但下面是一些重新调整AbstractMap用途的代码。SimpleEntry

     Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
            .map(f -> new AbstractMap.SimpleEntry<>(f, f.getAnnotation(Column.class)))
            .filter(entry -> entry.getValue() != null)
            .peek(entry -> entry.getKey().setAccessible(true))
            .collect(toMap(Map.Entry::getKey, entry -> entry.getValue().name()));

 类似资料:
  • 我需要将Java转换为的实例(包括映射内容) 我应该用什么来代替来使此代码可编译?

  • 由于我不想多次使用流来单独收集每个属性,也不想使用来收集每个属性,是否有任何方法可以用单个流来获得上述属性。

  • 我想通过调用来映射列表中的每个条目,它返回多个条目,然后将结果作为列表收集。 如果没有溪流,我会这样做: 我如何用流来完成这件事呢?这将给出一个编译错误:

  • 所以,在Clojure中,我可以这样说... 我得到了一个新的数据向量。 对于 Java 8 流,是否有一些简单的?例如,我在 上没有看到接受流的构造函数,也没有在 中看到某种帮助程序函数,也没有看到流接口。

  • 我有一个类具有以下签名: 我想将映射到在单个流中同时包含stringA和stringB的 或: 当然他们都不编译,但你明白了。 编辑: 示例:

  • 我对函数式编程和流的东西有点陌生,但我所知道的一点非常有用! 我认为除了与结合使用之外,还可以在其他情况下使用。当我还是uber n00b的时候,我花了很多时间重新设计Java集合框架,因为我不知道它在那里,所以我试着不重复我的错误。Java是否提供了一种很好的方法来完成的事情?我说错了吗? 谢谢! 编辑:下面是一些案例的示例数据。如果忽略步骤: