Guava Lists.transform - 如果一个输入不好怎么办?

时间:2013-01-14 12:05:51

标签: java collections exception-handling guava

我正在使用Lists.transform方法。在这里我有一个字符串输入一个CustomObject输出。字符串输入应包含一个冒号。然后我分裂这个冒号,然后从字符串的两个部分创建自定义对象。

所以输入是

a:b
c:d
e:f

并且输出是三个CustomObject包含a, b c, de, f

我的代码就像

return new ArrayList(Lists.transform(groups, new Function<String, CustomObject>() {
        @Override
        public CustomObject apply(String input) {
            String[] split = input.split(":");
            String one = split[0];
            String two = split[1];
            return new CustomObject(one, two);
        }
    }));

我的问题是我收到的列表来自用户。如果输入错误,我想跳过列表中的那个项目

所以如果输入列表包含

a:b
d
e,f
g:h

然后我想要两个包含a:bg:h

的CustomObject

这是否可以在番石榴中使用?

如果我以冗长的方式做这件事我会在for循环中继续并记录错误。

例如伪代码

for loop {
   if no colon present
      continue;
   create CustomObject
}

由于

3 个答案:

答案 0 :(得分:13)

如果您真的不想采用“经典”方式,则可以在转换之前始终使用Iterables.removeIf

但是“好老循环”的方式对你来说可能更好。番石榴开发者对这些功能习语的滥用感到不满({3}}:

  

过度使用Guava的函数式编程习惯用法会导致冗长,混乱,难以理解和低效的代码。这些是迄今为止最容易(也是最常见)被滥用的番石榴部分,当你为了使你的代码“单线”而荒谬的长度时,番石榴团队就会哭泣。

答案 1 :(得分:5)

我的方法会更实用,我会使用FluentIterable

return FluentIterable.from(groups).transform(new Function<String, CustomObject>() {
        @Override
        public CustomObject apply(String input) {
            String[] split = Iterables.toArray(
               Splitter.on(':').trimResults().omitEmptyStrings().split(input),
               String.class);
            if(split.length!=2) return null; // bad input data
            String one = split[0];
            String two = split[1];
            return new CustomObject(one, two);
        }
    }).filter(notNull()).toImmutableList();
         //   ^^  -- Predicates.*     

我将Function和Splitter都转换为常量。

答案 2 :(得分:2)

您可以更改函数以返回Optional,并使用Optional.presentInstances():

    return Optional.presentInstances(Iterables.transform(groups, new Function<String, Optional<CustomObject>>() {
        @Override
        public Optional<CustomObject> apply(String input) {
            if (*/ bad input data */) {
                return Optional.absent();
            }
            // ...
            return Optional.of(new CustomObject("", ""));
        }
    }));