我经常发现自己编写的代码可以从多个子列表中构建一个列表。作为一个简单的示例,假设您有一个需要验证为列表的列表。写这个(必须)的一种方法是:
import static com.google.common.collect.Lists.newArrayList;
import java.util.List;
public class Product {
private String name;
private int height;
public static List<String> validateList(List<Product> products) {
List<String> result = newArrayList();
valideListSize(products, result);
for (Product product : products) {
product.validate(result);
}
return result;
}
private static void valideListSize(List<Product> products,
List<String> result) {
if (products.size() > 1000) {
result.add("List too large");
}
}
private void validate(List<String> result) {
if (name.length() > 30) {
result.add("Name contains too many characters");
}
if (height > 40) {
result.add("Product too high");
}
}
}
但是,为了简单/维护/重用,我不喜欢将验证单个产品的逻辑与将验证结果列表添加到另一个现有列表中。我还认为改变参数会导致更难调试代码。所以我更喜欢功能性更强的风格。目前我通常会这样写(使用来自 Google Guava 的 newArrayList):
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import java.util.List;
public class Product {
private String name;
private int height;
public static List<String> validateList(List<Product> products) {
List<String> result = newArrayList();
result.addAll(valideListSize(products));
for (Product product : products) {
result.addAll(product.validate());
}
return result;
}
private static List<String> valideListSize(List<Product> products) {
if (products.size() > 1000) {
return singletonList("List too large");
}
return emptyList();
}
private List<String> validate() {
List<String> result = newArrayList();
if (name.length() > 30) {
result.add("Name contains too many characters");
}
if (height > 40) {
result.add("Product too high");
}
return result;
}
}
这会创建许多寿命很短的小型数组列表,其中许多通常是空的(没有验证错误)。这种代码在实践中会效率低下还是在生产环境中使用这种风格可以吗?有没有更有效的方法(可能使用 Guava)来做我想做的事,同时仍然保持代码干净、易于阅读并符合 Java 最佳实践?
作为一名专业的 Java 开发人员,您会做什么?
编辑:请参阅我对第一条评论的回答,为什么我更喜欢第二种方式。我更喜欢代码的可维护性/可读性而不是过早的优化,但是因为我在日常编程中经常看到这种模式,所以我想知道是否有一种至少同样干净的简单方法。使用某种连接列表视图怎么样,例如 Iterables.concat?或者这是否也创建了许多中间类?