我正在使用Lists.transform方法。在这里我有一个字符串输入一个CustomObject输出。字符串输入应包含一个冒号。然后我分裂这个冒号,然后从字符串的两个部分创建自定义对象。
所以输入是
a:b
c:d
e:f
并且输出是三个CustomObject包含a, b
c, d
和e, 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:b
和g:h
这是否可以在番石榴中使用?
如果我以冗长的方式做这件事我会在for循环中继续并记录错误。
例如伪代码
for loop {
if no colon present
continue;
create CustomObject
}
由于
答案 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("", ""));
}
}));