我喜欢Java有一个映射,你可以在映射中定义每个条目的类型,例如<String, Integer>。

我正在寻找的是一种类型的集合,其中集合中的每个元素都是一对值。对中的每个值都可以有自己的类型(如上面的String和Integer示例),该类型在声明时定义。

该集合将保持其给定的顺序,不会将其中一个值视为唯一键(就像在映射中一样)。

本质上,我希望能够定义一个数组类型<String,Integer>或任何其他2种类型。

我意识到,我可以让一个类只有2个变量,但这似乎过于啰嗦。

我也意识到我可以使用一个2D数组,但因为我需要使用不同的类型,我必须使他们OBJECT数组,然后我必须一直强制转换。

我只需要在集合中存储对,所以每个条目只需要两个值。像这样的东西不走阶级路线就存在吗?谢谢!


当前回答

在其他答案上展开一个通用的不可变Pair应该有一个静态方法,以避免调用构造函数使你的代码变得混乱:

class Pair<L,R> {
      final L left;
      final R right;

      public Pair(L left, R right) {
        this.left = left;
        this.right = right;
      }

      static <L,R> Pair<L,R> of(L left, R right){
          return new Pair<L,R>(left, right);
      }
}

如果你将静态方法命名为“of”或“pairOf”,代码就会变得流畅,因为你可以写任何一个:

    list.add(Pair.of(x,y)); // my preference
    list.add(pairOf(x,y)); // use with import static x.y.Pair.pairOf

遗憾的是,核心Java库在这些事情上是如此的稀少,以至于你必须使用common -lang或其他第三方来做这些基本的事情。升级到scala的另一个原因…

其他回答

我的意思是,尽管Java中没有Pair类,但有一些非常相似的东西:Map。条目

地图。输入文档

这就是HashMap或任何Map存储的内容(简化了一点)。

您可以创建一个Map实例,将值存储在其中并获取条目集。你将得到一个Set<Map。条目<K,V>>实际上就是你想要的。

So:

public static void main(String []args)
{    
    HashMap<String, Integer> values = new HashMap<String,Integer>();
    values.put("A", 235);//your custom data, the types may be different
    //more data insertions....
    Set<Map.Entry<String,Integer>> list = values.entrySet();//your list 
    //do as you may with it
}

只需创建一个类

class Tuples 
{ 
    int x;
    int y;
} 

然后创建这个对象的元组列表

List<Tuples> list = new ArrayList<>();

因此,您还可以以相同的方式实现其他新的数据结构。

您可以重用现有的Pair或来自“天知道有多少库已经提供了这样的类”的任何此类类。如果你不想从Hans Brende对这个问题的回答中得到任何东西,那么我不认为有任何理由不使用2D数组或对象数组列表/数组列表作为对/元组。你提到了不使用Array的原因:

我也意识到我可以使用一个2D数组,但因为我需要使用不同的类型,我必须使他们OBJECT数组,然后我必须一直强制转换。

即使您使用了来自Accepted Answer的Pair类,您仍然必须强制转换键和值对象。因为你想要存储所有类型的对象。换句话说,List<Pair> pairs与List<Pair<?扩展Object>>对,依次与Object[][2]或List<Object[]>或List<List<Object>>没有区别。因为如果你写下面的代码:

List<Pair> pairs = new ArrayList<>();

// logic for populating pairs into list goes here

// then after sometime you need an element
Pair p = pairs.get(whateverIndex);

Object key = p.getKey(); // We don't know type of key, right?
Object value = p.getValue(); // We don't know the exact type here as well

// All sorts of type guessing statemntes go here
GuessedTypeOfKey finallyMyKey = (GuessedTypeOfKey) key;
GuessedTypeOfValue finallyMyValue = (GuessedTypeOfValue) value;

你仍然需要进行类型转换。所以我找不到任何其他理由不使用2d对象数组或对象数组列表/数组列表作为对/元组。下面是使用List和数组的代码

List<Object[]> simplePairs = new ArrayList<>();

// Add values to pairs
simplePairs.add(new Object[]{1,"One"});
simplePairs.add(new Object[]{"Another Key of Different Type","Value"});
simplePairs.add(new Object[]{"Another Key of Different Type",new AnotherType("Another Value Type")});

// get values
Object[] pair = simplePairs.get(whateverIndex);
Object key = pair[0];
Object value = pair[1];

Spring在Data Utils包org.springframework.data.util中有一个Pair<S,T>类型

Pair<String,Integer> pair = Pair.of("Test", 123);
System.out.println(pair.getFirst());
System.out.println(pair.getSecond());

Apache common lang3有Pair类和本线程中提到的少数其他库,在Java中等价于c++ Pair<L,R> ?

匹配你最初问题要求的例子:

List<Pair<String, Integer>> myPairs = new ArrayList<Pair<String, Integer>>();
myPairs.add(Pair.of("val1", 11));
myPairs.add(Pair.of("val2", 17));

//...

for(Pair<String, Integer> pair : myPairs) {
  //following two lines are equivalent... whichever is easier for you...
  System.out.println(pair.getLeft() + ": " + pair.getRight());
  System.out.println(pair.getKey() + ": " + pair.getValue());
}