[英]What's the most efficient way to write this method?
该方法返回一个“成分”object,它是根据配方 txt 文件中的给定行构建的。 注意: InvalidIngredientException
类似于InputMismatchException
的Ingredient
版本。 这不是由给定配方文件中的任何行抛出的。
public static Ingredient parseString(String line)
throws InvalidIngredientException {
double quantity = 1;
String measurement = "";
String[] parts = line.split(";");
if (parts.length == 1) {
throw new InvalidIngredientException(EXP_MSG);
}
if (!parts[0].trim().isEmpty()
&& !(Double.parseDouble(parts[0]) == 1)) {
quantity = Double.parseDouble(parts[0].trim());
}
if (!parts[1].trim().isEmpty()) {
measurement = parts[1].trim();
}
return new Ingredient(quantity, measurement, parts[2].trim());
}
配方文件如下所示:
Cranberry Oatmeal Chews
8; tablespoon; butter
2; tablespoon; oil
1; cup; light brown sugar
1; ; zest of one orange
6; tablespoon; sour cream
2; teaspoon; vanilla
1.5; cup; flour
.5; teaspoon; baking soda
1; teaspoon; cinammon
.5; teaspoon; salt
2; cup; oats
1.5; cup; dried cranberries
.5; cup; walnuts
该方法有效,但我觉得它可以使用更少的代码。
您正在尝试做的事情称为“将 CSV 行绑定到一个对象”。 有很多不错的库可以解析 CSV,大多数成熟的库也提供绑定功能。 还有基于注释的代码生成启用框架,如 Lombok 或 Jackson,它使 Java 更接近方便的语言,如 Scala,使您免于手动编写非常冗长的 getters/setters(构建过程可能有点复杂) .
一旦你使用了正确的搜索词,你就会发现大量的例子。 一个做我上面描述的就是这个,下面是一个根据你的命名调整的版本。 它正在使用 Jackson。
带有 Jackson 注释的 Object 定义:
@JsonPropertyOrder({"quantity", "measure", "ingredient"})
public class Ingredient {
public double quantity;
public String measure;
public int ingredient;
}
使用 Jackson CsvMapper的调用代码:
List<Ingredient> result = new CsvMapper()
.readerWithTypedSchemaFor(Ingredient.class)
.readValues(csvFile)
.readAll();
我不习惯Java,所以这段代码可能会有一些小错误。 如果你看到一个,请随意编辑。
从 C# 的角度来看,我将进行以下更改:
.trim()
调用移到一个地方。 在这里,我通过使用of()
创建Stream
然后调用map
(假设 Java 8 或更新版本)将输入行拆分成多个parts
之后执行此操作。quantity
和measurement
的默认值的行。 因为我们不必修剪,所以我们可以使用三元运算符在同一行上声明和实例化变量。parts[1]
是否为空。 由于""
是后备值,因此parts[1]
是否也是""
也没关系。 这也意味着您不需要中间measurement
变量。public static Ingredient parseString(String line)
throws InvalidIngredientException {
String[] parts = Stream.of(line.split(";")).map(p => p.trim()).toArray();
if (parts.length == 1) {
throw new InvalidIngredientException(EXP_MSG);
}
double quantity = parts[0].isEmpty() ? 1 : Double.parseDouble(parts[0]);
return new Ingredient(quantity, parts[1], parts[2]);
}
如果parts.length == 0
或parts[0]
无法解析为Double
,您也有可能抛出InvalidIngredientException
以外的错误。 我不确定在声明你的方法可以抛出哪些异常时你应该有多严格,但这里有一个版本应该捕获任何异常并且只返回你声明的InvalidIngredientException
。
public static Ingredient parseString(String line)
throws InvalidIngredientException {
try {
String[] parts = Stream.of(line.split(";")).map(p => p.trim()).toArray();
double quantity = parts[0].isEmpty() ? 1 : Double.parseDouble(parts[0]);
return new Ingredient(quantity, parts[1], parts[2]);
}
catch (Exception e) {
throw new InvalidIngredientException(EXP_MSG);
}
}
您可以做一些小事情来使您的代码看起来更好并稍微提高性能。
else if...else
语法。 这将使您的代码不仅更短,而且更易于阅读。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.