【问题标题】:Java type that holds two primitives of any primitive type包含任意原始类型的两个原始类型的 Java 类型
【发布时间】:2016-01-22 11:04:29
【问题描述】:

我想在一个字段中存储两个原始值(我在这里将String 作为原始值包括在内)。例如,我可能想存储一个String 和一个int,如下所示:

("hello", 42)

所以如果我要查找的类型是X,我希望能够声明一个字段

private X myX = new X("hello", 42);

或其他一些能给我同样结果的咒语。

我试图弄清楚该字段必须是什么类型。它必须接受任何 Java 原始类型和 String,因此它可以是 String + intString + float... 实际上是原始 (+ String) 类型的任何组合。本质上,要从函数式语言中借用一个概念,我只想要一个仅限于原语的tuple。但是 Java 没有。

由于它们是基元,所以泛型不能很好地工作。而且我不确定我对装箱/拆箱的感觉。

我可以在 Java 中使用的最佳数据类型/结构是什么?

【问题讨论】:

  • “所有类型”是什么意思?所有原始类型 + 字符串(int、boolean、short、float 等)还是所有对象?
  • 不只是原始类型
  • HashMap ?
  • 好的,我会编辑抱歉造成的混乱
  • 这真的取决于你想要达到的目标......而且这种“所有类型”的机制总是很难使用!

标签: java types


【解决方案1】:

不要认为有办法使用内置的 Java 库来做到这一点。但是,可以像这样在 Scala 语言中编写与 Tuple2 类相同的 Tuple 类:

public class Tuple<K, V> {
        private K first;
        private V second;

        // create tuple only with static method "of"
        private Tuple(K first, V second) {
            this.first = first;
            this.second = second;

        }

        public static <K, V> Tuple<K, V> of(K a, V b) {
            return new Tuple<K, V>(a, b);
        }

        public Tuple<V, K> swap() {
            return new Tuple<V, K>(second, first);
        }

        public K getFirst() {
            return this.first;
        }

        public V getSecond() {
            return this.second;
        }

        @Override
        public String toString() {
            return "(" + first.toString() + "," + second.toString() + ")";
        }

        public static void main(String[] args) {
            Tuple myTuple = Tuple.of("hello", 2);

            System.out.println("toString: "+myTuple);
            System.out.println("First: "+myTuple.getFirst());
            System.out.println("Swap: "+ myTuple.swap());
        }

    }

    Output:

    toString: (hello,2)
    First: hello
    Swap: (2,hello)

【讨论】:

    【解决方案2】:

    如果您真的想将值存储为一种原始类型,则必须对它们进行“编码”。

    例如:

    String field = "hello;42";
    String[] values = field.split(";");
    int intValue = Integer.parseInt(values[1]);
    

    【讨论】:

      【解决方案3】:

      由于您只使用原语(和String),因此您似乎希望尽可能避免自动装箱和拆箱。这意味着您不能使用泛型。 (原始类型不能用作类型参数。)您似乎还想避免不必要的提升(例如,如果您将 floats 存储为 doubles 您会保留原始值,但会丢失事实它实际上是float)。

      一个相当复杂的解决方案是创建一组PrimitivePair 类,一个用于您要存储的原始类型的每种组合,以及一个用于轻松构造它们的工厂类。例如,您可能有以下三个类来存储各种原语对:

      package primitivepair;
      
      public class PrimitivePairStringInt
      {
         final String s;
         final int i;
      
         PrimitivePairStringInt(final String s, final int i)
         {
            this.s = s;
            this.i = i;
         }
      
         public String getFirstValue()
         {
            return s;
         }
      
         public int getSecondValue()
         {
            return i;
         }
      }
      

      package primitivepair;
      
      public class PrimitivePairFloatDouble
      {
         final float f;
         final double d;
      
         PrimitivePairFloatDouble(final float f, final double d)
         {
            this.f = f;
            this.d = d;
         }
      
         public float getFirstValue()
         {
            return f;
         }
      
         public double getSecondValue()
         {
            return d;
         }
      }
      

      package primitivepair;
      
      public class PrimitivePairCharByte
      {
         final char c;
         final byte b;
      
         PrimitivePairCharByte(final char c, final byte b)
         {
            this.c = c;
            this.b = b;
         }
      
         public char getFirstValue()
         {
            return c;
         }
      
         public byte getSecondValue()
         {
            return b;
         }
      }
      

      它们将由以下工厂类创建:

      package primitivepair;
      
      public class PrimitivePairFactory
      {
         public static PrimitivePairCharByte createPrimitivePair(final char c, final byte b)
         {
            return new PrimitivePairCharByte(c, b);
         }
      
         public static PrimitivePairFloatDouble createPrimitivePair(final float f, final double d)
         {
            return new PrimitivePairFloatDouble(f, d);
         }
      
         public static PrimitivePairStringInt createPrimitivePair(final String s, final int i)
         {
            return new PrimitivePairStringInt(s, i);
         }
      }
      

      您当然可以为其他组合添加更多类和工厂方法。

      我想创建一个抽象的PrimitivePair 类,该类将具有getFirstValue()getSecondValue() 方法的创建方法 方法声明,但这需要返回类型协方差起作用对于原始人,我不相信它。

      【讨论】:

        【解决方案4】:

        Java 没有内置的 Tuple 类型。

        您可以使用标准的Map.Entry<K,V>,但如果可能的话,我个人建议使用 Apache Commons Lang3 的 Tuple 类型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-06-26
          • 2013-02-02
          • 1970-01-01
          • 1970-01-01
          • 2016-03-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多