【问题标题】:How to parse String array into different primitive arrays如何将字符串数组解析为不同的原始数组
【发布时间】:2020-05-13 16:09:48
【问题描述】:

给定一个表示值的字符串数组和另一个表示原始类型的字符串,我需要将值字符串解析为给定原始类型的数组,例如"double" 和 ["1", "2", "3"] 将变为 [1.0, 2.0, 3.0]。

想到的第一个解决方案如下所示:

String format = "int16";
String[] values = {"1", "2", "3"};
switch (format)
{
    case "int16":
        short[] short_values = new short[values.length];
        for (int i = 0; i < values.length; i++) short_values[i] = Short.parseShort(values[i]);
        foo(short_values);
        break;
}

虽然这行得通,但我不禁觉得有一种更优雅的方法可以做到这一点。 Java中是否有某种方法可以存储对静态方法的引用和对原始类型的引用,以便您可以这样:

Functor parser;
Type type;

switch (format)
{
    case "int16":
        parser = Short.parseShort;
        type = short;
        break;
}
List<type> value_list = new ArrayList<>();
for (String value : values) value_list.add(parser(value));
foo(value_list.toArray(new type[0]);

假设这是不可能的,有没有其他方法可以改进第一个解决方案?

谢谢

【问题讨论】:

    标签: java


    【解决方案1】:

    @Couper 的例子很不错。你也可以这样做。

    public class MainClass {
    
        public static void main(String[] args) {
            String format = "int16";
            String[] values = {"1", "2", "3"};
            ParserInterface pi = null;
            Class<?> classType = null;
            switch(format) {
            case "int16":
                pi = Short::parseShort;
                classType = Short.class;
                break;
            }
            for(String value : values) {
                System.out.println(classType.cast(pi.parse(value)));
            }
        }
    
    }
    
    @FunctionalInterface
    interface ParserInterface {
        public Object parse(String data);
    }
    

    您可以使用函数式接口来保存方法引用并设置类类型以键入解析值。它对我有用!请分享您的反馈和疑虑。

    【讨论】:

    • 我认为这是一个更好的解决方案,因为您可以实现解析并且不依赖于类构造函数。
    • 这看起来非常接近我的需要!有没有办法可以使用 classType 变量来创建数组或数组列表?
    • 您不能在运行时创建arrayList,但您可以像这样使用ListList&lt;T&gt; l = new ArrayList&lt;&gt;(); for (String value : values) { l.add((T) classType.cast(pi.parse(value))); }
    【解决方案2】:

    如果您使用的是 Java 8 或更高版本,并且如果您不介意生成的数组是“盒装”类型而不是原始类型(IntegerDouble 等),那么流可以是一种优雅的解决方案。

    这是一个代码示例:

    import java.util.Arrays;
    import java.util.stream.Stream;
    
    public class Streams {
        public static void main(String [] args) {
            String[] values = {"1", "2", "3"};
            String format = "double";
    
            Stream<String> stream = Arrays.stream(values);
            Object [] arr = null;
    
            switch (format) {
                case "int16":
                    arr = stream.map(Short::parseShort).toArray();
                    break;
    
                case "double":
                    arr = stream.map(Double::parseDouble).toArray();
                    break;
            }
    
            for (Object o : arr) System.out.println(o);
        }
    }
    

    如果您想要原始数组,可以使用流方法mapToIntmapToDouble(带有Integer::intValue 等参数),但您必须为每种情况定义一个单独的数组。

    您也可以稍后在代码中使用另一个流来拆箱整个数组,如下所述:(Un)boxing primitive arrays in Java

    【讨论】:

      【解决方案3】:

      你可以这样做:

      private <T> T parse(String value, Class<T> type) {
          try {
              return type.getConstructor(String.class).newInstance(value);
          } catch (Exception e) {
              return null;
          }
      }
      

      只要您需要转换为的类有一个带有单个 String 参数的构造函数,它就可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-18
        • 2017-01-27
        • 2021-11-05
        • 2017-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-29
        相关资源
        最近更新 更多