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呢?