Java值集合对? (元组?)

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

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

该集合将保持其给定的顺序,并不会将其中一个值视为唯一键(如在地图中)。

基本上我想能够定义一个类型为<String,Integer>或任何其他2种类型的ARRAY。

我意识到,除了2个变量之外,我可以做一个班级,但是看起来过于冗长。

我也意识到我可以使用2D数组,但是由于需要使用不同的类型,所以我必须使它们成为OBJECT数组,然后我必须一直投射。

我只需要在集合中存储对,所以每个条目只需要两个值。 像这样的东西存在没有去上课路线? 谢谢!

Pair类是那些“gimme”泛型例子之一,很容易就可以自己写。 例如,我的头顶上:

 public class Pair<L,R> { private final L left; private final R right; public Pair(L left, R right) { this.left = left; this.right = right; } public L getLeft() { return left; } public R getRight() { return right; } @Override public int hashCode() { return left.hashCode() ^ right.hashCode(); } @Override public boolean equals(Object o) { if (!(o instanceof Pair)) return false; Pair pairo = (Pair) o; return this.left.equals(pairo.getLeft()) && this.right.equals(pairo.getRight()); } } 

是的,这在网络上的多个地方存在,具有不同程度的完整性和特征。 (我上面的例子是不可改变的。)

AbstractMap.SimpleEntry

容易,你正在寻找这个:

 java.util.List<java.util.Map.Entry<String,Integer>> pairList= new java.util.ArrayList<>(); 

你怎么填满它?

 java.util.Map.Entry<String,Integer> pair1=new java.util.AbstractMap.SimpleEntry<>("Not Unique key1",1); java.util.Map.Entry<String,Integer> pair2=new java.util.AbstractMap.SimpleEntry<>("Not Unique key2",2); pairList.add(pair1); pairList.add(pair2); 

这简化为:

 Entry<String,Integer> pair1=new SimpleEntry<>("Not Unique key1",1); Entry<String,Integer> pair2=new SimpleEntry<>("Not Unique key2",2); pairList.add(pair1); pairList.add(pair2); 

而且,在createEntry方法的帮助下,可以进一步减少冗长:

 pairList.add(createEntry("Not Unique key1", 1)); pairList.add(createEntry("Not Unique key2", 2)); 

由于ArrayList不是最终的,因此可以将其暴露为一个方法(和前面提到的createEntry方法),从而产生语法上的简洁:

 TupleList<java.util.Map.Entry<String,Integer>> pair = new TupleList<>(); pair.of("Not Unique key1", 1); pair.of("Not Unique key2", 2); 

这些内置的类也是一个选项:

  • AbstractMap.SimpleEntry
  • AbstractMap.SimpleImmutableEntry

在Java 9中,您可以简单地编写: Map.entry(key, value)来创建一个不可变的对。

注意:要使用此方法,键和值都不能为空 ,并且返回的Map.Entry对象不可序列化 。 如果您希望使用可序列化的对,或者希望允许空键或值,则可以使用更详细的AbstractMap.SimpleImmutableEntry ,它可在Java 6及更高版本中使用。

如果您正在使用Java 8(或Java 9的javafx.base模块),则可以使用较为详细的,更通用的javafx.util.Pair

如果您正在为Android编写代码,则可以使用android.util.Pair

如果您使用Apache Commons Lang ,则可以使用org.apache.commons.lang3.tuple.Pair

如果上述解决方案都不能解决问题,则可以简单地复制并粘贴以下代码(与接受的答案中列出的类不同,它可以防范NullPointerExceptions):

 import java.util.Objects; public class Pair<K, V> { public final K key; public final V value; public Pair(K key, V value) { this.key = key; this.value = value; } public boolean equals(Object o) { return o instanceof Pair && Objects.equals(key, ((Pair<?,?>)o).key) && Objects.equals(value, ((Pair<?,?>)o).value); } public int hashCode() { return 31 * Objects.hashCode(key) + Objects.hashCode(value); } public String toString() { return key + "=" + value; } } 

Apache常见的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()); } 

任何为Android开发的人,都可以使用android.util.Pair 。 🙂

那么“Apache Commons Lang 3” Pair类和相关的子类呢?

  import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; ... @SuppressWarnings("unchecked") Pair<String, Integer>[] arr = new ImmutablePair[]{ ImmutablePair.of("A", 1), ImmutablePair.of("B", 2)}; // both access the 'left' part String key = arr[0].getKey(); String left = arr[0].getLeft(); // both access the 'right' part Integer value = arr[0].getValue(); Integer right = arr[0].getRight(); 

ImmutablePair是一个特定的子类,它不允许修改对中的值,但也有其他的实现具有不同的语义。 这些是Maven的坐标,如果你需要的话。

  <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> 

你可以写一个通用的Pair <A,B>类,并在数组或列表中使用它。 是的,你必须写一个类,但是你可以为所有类型重用相同的类,所以你只需要做一次。

我要问你是否不想用List<Pair<T, U>> ? 但是当然,JDK没有Pair <>类。 但是一个快速的Google在维基百科和forums.sun.com上找到了一个。 干杯

你所描述的首选解决方案是一个列表(即列表)。

要做到这一点,你会创建一个Pair类用于你的收藏。 这是一个有用的工具类添加到您的代码库。

Sun JDK中提供的类似于典型的Pair类的功能最接近的类是AbstractMap.SimpleEntry。 你可以使用这个类,而不是创建自己的Pair类,尽管你将不得不忍受一些尴尬的限制,我想大多数人会因为不是SimpleEntry的预期角色而皱眉。 例如,SimpleEntry没有“setKey()”方法,也没有默认的构造函数,所以你可能会发现它的限制。

请记住,Collections是为了包含单一类型的元素而设计的。 相关的实用程序接口(如Map)实际上并不是集合(即Map没有实现Collection接口)。 一个Pair不会实现Collection接口,但是在构建更大的数据结构中显然是一个有用的类。

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

 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 xyPair.pairOf 

它的真正的耻辱,核心Java库是如此稀疏的事情,你必须使用commons-lang或其他第三方做这样的基本的东西。 升级到Scala的另一个原因是…

这是基于JavaHelp4u的代码。

不详细,并显示如何做一行,如何循环的东西。

 //======> Imports import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; //======> Single Entry SimpleEntry<String, String> myEntry = new SimpleEntry<String, String>("ID", "Text"); System.out.println("key: " + myEntry.getKey() + " value:" + myEntry.getValue()); System.out.println(); //======> List of Entries List<Entry<String,String>> pairList = new ArrayList<>(); //-- Specify manually Entry<String,String> firstButton = new SimpleEntry<String, String>("Red ", "Way out"); pairList.add(firstButton); //-- one liner: pairList.add(new SimpleEntry<String,String>("Gray", "Alternate route")); //Ananomous add. //-- Iterate over Entry array: for (Entry<String, String> entr : pairList) { System.out.println("Button: " + entr.getKey() + " Label: " + entr.getValue()); } 

Apache Crunch也有一个Pair类: http : //crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.html

就像创建一个类一样

 class tuples { int x; int y; } 

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

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

所以你也可以用同样的方法实现其他新的数据结构。

我的意思是,即使Java中没有Pair类,也有相当类似的东西: Map.Entry

Map.Entry文档

这是(简化很多)什么HashMap ,或者实际上任何Map存储。

你可以创建一个Map实例存储你的值,并获取条目集。 你最终会得到一个Set<Map.Entry<K,V>> ,这就是你想要的。

所以:

 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 } 

那么com.sun.tools.javac.util.Pair呢?