替代新方法以避免重复代码

时间:2020-02-21 14:24:48

标签: java java-stream

我想将相同的操作应用于不同的流(目前使用Java 8)

背景:我正在尝试从Tika 元数据对象中获取尺寸数据

以下内容有效,但重复代码(元数据是Tika 元数据对象):

    private static void processDimensions(final Metadata metadata) {
        Optional<Integer> optWidth = Arrays.stream(new String[] {"tiff:ImageWidth", "Image Width"})
                .map(metadata::get)
                .filter(Objects::nonNull)
                .map(v -> v.replace("pixels", ""))
                .map(Integer::parseInt).findFirst();
        // do something with optWidth

        Optional<Integer> optHeight = Arrays.stream(new String[] {"tiff:ImageLength", "Image Height"})
                .map(metadata::get)
                .filter(Objects::nonNull)
                .map(v -> v.replace("pixels", ""))
                .map(Integer::parseInt).findFirst();
        // do something with optHeight
    }

至此,我不再重复代码:

    private static void processDimensions(final Metadata metadata) {
        Optional<Integer> optWidth = processDimension(metadata, "tiff:ImageWidth", "Image Width");
        // do something with optWidth

        Optional<Integer> optHeight = processDimension(metadata, "tiff:ImageLength", "Image Height");
        // do something with optHeight
    }

    private static Optional<Integer> processDimension(final Metadata metadata, @NonNull final String... keys) {
        return Arrays.stream(keys).map(metadata::get).filter(Objects::nonNull).map(v -> v.replace("pixels", ""))
                .map(Integer::parseInt).findFirst();
    }

是否可以在没有单独的方法(例如 processDimensions()中的Function)的情况下执行相同的操作?看起来如何?

2 个答案:

答案 0 :(得分:4)

是的,将其声明为java.util.Function,然后重新使用。

Function<String[], OptionalInt> funct = keys -> Arrays.stream(keys)
    .map(metadata::get)
    .filter(Objects::nonNull)
    .map(v -> v.replace("pixels", ""))
    .mapToInt(Integer::parseInt)
    .findFirst();

这是你的称呼方式。

funct.apply(strArr);

实际上,声明方法给出了更易读的名称,例如processDimensions,并且声明的参数类型具有比lambda更具描述性的名称,因此对我来说更具可读性。除非您精通流,否则可能很难阅读该管道。而且,方法定义了事实上的API,但是流管道通常没有。

答案 1 :(得分:0)

这样的作品行吗?

        private static Optional<Integer> processDimension(final Metadata, dim) {
            return Arrays.stream(new String[] {"tiff:Image" + dim, "Image " + dim})
                    .map(metadata::get)
                    .filter(Objects::nonNull)
                    .map(v -> v.replace("pixels", ""))
                    .map(Integer::parseInt).findFirst();
        }

然后这样称呼它。

        int width = processDimension(metadata, "Width").get();
        int height = processDimension(metadata, "Height").get();

您可能想使用其他方法来检索optional以提供默认值。