Java 避免多个if语句-不同的数据类型

Java 避免多个if语句-不同的数据类型,java,if-statement,Java,If Statement,我有许多if语句,我想避免它们 我尝试使用HashMap,但它不适用于数据类型。请看下面的代码,我有。这只是第一个if语句,但我还有更多。。。 字段是数据类型 if (field.equals(DataTypes.IntegerType)) { x = Integer.valueOf(); } [...] else if (field instanceof org.apache.spark.sql.types.TimestampType) { try {

我有许多
if
语句,我想避免它们

我尝试使用HashMap,但它不适用于数据类型。请看下面的代码,我有。这只是第一个
if
语句,但我还有更多。。。 字段是数据类型

   if (field.equals(DataTypes.IntegerType)) {
     x = Integer.valueOf();
    } 

    [...]
else if (field instanceof org.apache.spark.sql.types.TimestampType) {
  try {
    x = Timestamp.valueOf();
  } catch (Exception) {
    try {
      columns[i] = Timestamp.valueOf(...).toLocalDateTime());
    } catch (Exception) {

      throw new ParseException("...");
    }
  }
   [...]


    else {
    x = null
   }

我是否可以避免那么多其他
if
语句?

您可以使用switch,但if/else仍然优于任何其他方法。

您可以使用switch,但if/else仍然优于任何其他方法。

我假设数据类型是一个枚举。 最简单的方法需要访问DataTypes枚举以添加由每个类型实现的方法

enum DataTypes {
    IntegerType() {
        public Object valueFrom(String s) {
            return Integer.parseInt(s);
        }
    },
    LongType() {
        return Long.parseLong(s);
    }; // CONTINUE WITH ALL TYPES

    public Object valueFrom(String s) {
        return s;
    }
}
然后将代码简化为:

columns[i] = field.valueFrom(s);
您还可以将convert方法分开,并且在每个枚举类型中都有一个字段,其中包含对该类型的converter方法的引用:

enum DataTypes {
    IntegerType(Integer::parseInt),
    LongType(Long::parseLong); // CONTINUE WITH ALL TYPES

    private Function<String,Object> converter;

    DataTypes(Function<String,Object> converter) {
        this.converter = converter;
    }

    public Object valueFrom(String s) {
        return converter.apply(s);
    }
}
enum数据类型{
IntegerType(Integer::parseInt),
LongType(Long::parseLong);//继续所有类型
专用函数转换器;
数据类型(函数转换器){
这个。转换器=转换器;
}
公共对象值来源(字符串s){
返回转换器。应用;
}
}

我假设数据类型是一个枚举。 最简单的方法需要访问DataTypes枚举以添加由每个类型实现的方法

enum DataTypes {
    IntegerType() {
        public Object valueFrom(String s) {
            return Integer.parseInt(s);
        }
    },
    LongType() {
        return Long.parseLong(s);
    }; // CONTINUE WITH ALL TYPES

    public Object valueFrom(String s) {
        return s;
    }
}
然后将代码简化为:

columns[i] = field.valueFrom(s);
您还可以将convert方法分开,并且在每个枚举类型中都有一个字段,其中包含对该类型的converter方法的引用:

enum DataTypes {
    IntegerType(Integer::parseInt),
    LongType(Long::parseLong); // CONTINUE WITH ALL TYPES

    private Function<String,Object> converter;

    DataTypes(Function<String,Object> converter) {
        this.converter = converter;
    }

    public Object valueFrom(String s) {
        return converter.apply(s);
    }
}
enum数据类型{
IntegerType(Integer::parseInt),
LongType(Long::parseLong);//继续所有类型
专用函数转换器;
数据类型(函数转换器){
这个。转换器=转换器;
}
公共对象值来源(字符串s){
返回转换器。应用;
}
}

您可以保留转换的静态映射:

private static final Map<DataType, Function<String, ?>> stringConverters;

static {
    Map<DataType, Function<String, ?>> map = new EnumMap<>(DataType.class);

    map.put(DataType.IntegerType,   Integer::valueOf);
    map.put(DataType.LongType,      Long::valueOf);
    map.put(DataType.DoubleType,    Double::valueOf);
    map.put(DataType.FloatType,     Float::valueOf);
    map.put(DataType.StringType,    Function.identity());
    map.put(DataType.BinaryType,    Binary::fromString);

    if (!map.keySet().containsAll(EnumSet.allOf(DataType.class))) {
        throw new RuntimeException(
            "Programming error: Not all DataType values accounted for.");
    }

    stringConverters = Collections.unmodifiableMap(map);
}

// ...

    columns[i] = stringConverters.get(field).apply(s);
私有静态最终映射字符串转换器;
静止的{
Map Map=新的枚举映射(DataType.class);
put(DataType.IntegerType,Integer::valueOf);
map.put(DataType.LongType,Long::valueOf);
put(DataType.DoubleType,Double::valueOf);
put(DataType.FloatType,Float::valueOf);
map.put(DataType.StringType,Function.identity());
put(DataType.BinaryType,Binary::fromString);
如果(!map.keySet().containsAll(EnumSet.allOf(DataType.class))){
抛出新的运行时异常(
“编程错误:不是所有的数据类型值都被解释。”);
}
stringConverters=Collections.unmodifiableMap(映射);
}
// ...
列[i]=stringConverters.get(field).apply(s);

containsAll
检查有助于确保您不会忽略任何数据类型值。

您可以保留转换的静态映射:

private static final Map<DataType, Function<String, ?>> stringConverters;

static {
    Map<DataType, Function<String, ?>> map = new EnumMap<>(DataType.class);

    map.put(DataType.IntegerType,   Integer::valueOf);
    map.put(DataType.LongType,      Long::valueOf);
    map.put(DataType.DoubleType,    Double::valueOf);
    map.put(DataType.FloatType,     Float::valueOf);
    map.put(DataType.StringType,    Function.identity());
    map.put(DataType.BinaryType,    Binary::fromString);

    if (!map.keySet().containsAll(EnumSet.allOf(DataType.class))) {
        throw new RuntimeException(
            "Programming error: Not all DataType values accounted for.");
    }

    stringConverters = Collections.unmodifiableMap(map);
}

// ...

    columns[i] = stringConverters.get(field).apply(s);
私有静态最终映射字符串转换器;
静止的{
Map Map=新的枚举映射(DataType.class);
put(DataType.IntegerType,Integer::valueOf);
map.put(DataType.LongType,Long::valueOf);
put(DataType.DoubleType,Double::valueOf);
put(DataType.FloatType,Float::valueOf);
map.put(DataType.StringType,Function.identity());
put(DataType.BinaryType,Binary::fromString);
如果(!map.keySet().containsAll(EnumSet.allOf(DataType.class))){
抛出新的运行时异常(
“编程错误:不是所有的数据类型值都被解释。”);
}
stringConverters=Collections.unmodifiableMap(映射);
}
// ...
列[i]=stringConverters.get(field).apply(s);


containsAll
检查有助于确保您不会忽略任何数据类型值。

字段的类型是什么?最后的
else
在哪里?通过使用接口和多态性,可以避免使用
if(type==foo)foo.doSomething()
。应该会给你一些启发。但是请记住,有时候有很多if/else是可以的,关于使用哪种模式没有硬性规定。正如您可能已经猜到的:为了编写更好的代码,我们必须了解数据类型“是什么”:因此我们需要更多的上下文。字段是架构字段中的数据类型。
开关
语句不会减少行数,但通常更容易读取
字段
的类型是什么?最后的
else
在哪里?通过使用接口和多态性,可以避免使用
if(type==foo)foo.doSomething()
。应该会给你一些启发。但是请记住,有时候有很多if/else是可以的,关于使用哪种模式没有硬性规定。正如您可能已经猜到的:为了编写更好的代码,我们必须了解数据类型“是什么”:因此我们需要更多的上下文。字段是架构字段中的数据类型。
开关
语句不会减少行数,但通常更容易阅读“if/else优于任何其他方法”是谁说的?对于一个或两个值,请详细说明为什么
if
/
else
优于任何其他方法,if-else没有什么问题,但是对于多个值,如果else条件分支对变量非常有用,那么开关块将使整个o部分更易于读取conditions@AakashdeepSingh您所说的“可变条件”是什么意思?“if/else优于任何其他方法”谁说的?你能解释一下为什么
如果
/
else
优于任何其他方法吗?对于一个或两个值,if-else没有错,但对于多个值,如果其他条件分支对变量非常有用,那么开关块将使整个部分更易于读取conditions@AakashdeepSingh“可变条件”是什么意思?数据类型来自import org.apache.spark.sql.types.DataTypesAh,在这种情况下,我将使用VGR的答案。数据类型来自import org.apache.spark.sql.types.DataTypesAh,在这种情况下,我将使用VGR的答案。谢谢您的回答。它也适用于地图吗。