我喜欢Java有一个Map,你可以在其中定义地图中每个条目的类型
.
我正在寻找的是一种集合,其中集合中的每个元素都是一对值.对中的每个值都可以有自己的类型(如上面的String和Integer示例),它是在声明时定义的.
该集合将保持其给定的顺序,并且不会将其中一个值视为唯一键(如在地图中).
基本上我希望能够定义类型的ARRAY
或任何其他2种类型.
我意识到我可以创建一个只有2个变量的类,但这看起来过于冗长.
我也意识到我可以使用2D数组,但由于我需要使用不同的类型,我必须使它们成为OBJECT数组,然后我必须一直投射.
我只需要在集合中存储对,所以每个条目只需要两个值.如果没有上课路线,这样的事情会存在吗?谢谢!
你很容易找到这个:
java.util.List> pairList= new java.util.ArrayList<>();
你怎么能填补它?
java.util.Map.Entrypair1=new java.util.AbstractMap.SimpleEntry<>("Not Unique key1",1); java.util.Map.Entry pair2=new java.util.AbstractMap.SimpleEntry<>("Not Unique key2",2); pairList.add(pair1); pairList.add(pair2);
这简化为:
Entrypair1=new SimpleEntry<>("Not Unique key1",1); Entry 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
不是最终的,它可以被子类化以暴露of
方法(和上述createEntry
方法),从而导致语法简洁:
TupleList> pair = new TupleList<>(); pair.of("Not Unique key1", 1); pair.of("Not Unique key2", 2);
Pair类是那些"gimme"泛型示例之一,很容易自己编写.例如,在我的头顶:
public class Pair{ 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()); } }
是的,这存在于网络的多个地方,具有不同程度的完整性和功能.(我上面的例子是不可变的.)
在Java 9中,您可以简单地编写:Map.entry(key, value)
创建一个不可变对.
注意:此方法不允许键或值为null.例如,如果要允许空值,则需要将其更改为:Map.entry(key, Optional.ofNullable(value))
.
在Java 8中,您可以使用更通用的目的javafx.util.Pair
来创建不可变的,可序列化的对.这个类也允许null键和空值.(在Java 9中,此类包含在javafx.base
模块中).编辑:从Java 11开始,JavaFX已经与JDK分离,所以你需要额外的maven工件org.openjfx:javafx-base.
在Java 6及更高版本中,您可以AbstractMap.SimpleImmutableEntry
对不可变对使用更详细,或者AbstractMap.SimpleEntry
对可以更改其值的对使用更详细.这些类还允许null键和null值,并且是可序列化的.
如果您正在为Android编写,只需使用Pair.create(key, value)
创建不可变对.
Apache Commons Lang
提供了Pair.of(key, value)
创建不可变,可比较,可序列化对的帮助.
如果您正在使用包含基元的对,Eclipse Collections提供了一些非常有效的原始对类,它们将避免所有低效的自动装箱和自动拆箱.
例如,您可以使用PrimitiveTuples.pair(int, int)
创建IntIntPair
或PrimitiveTuples.pair(float, long)
创建FloatLongPair
.
使用Project Lombok,您只需编写以下代码即可创建不可变对类:
@Value public class Pair{ K key; V value; }
龙目岛将在构造函数中,吸气剂,填充equals()
,hashCode()
和toString()
方法自动生成的字节码为您服务.如果您想要静态工厂方法而不是构造函数,例如a Pair.of(k, v)
,只需将注释更改为:@Value(staticConstructor = "of")
.
如果以上解决方案都没有浮动您的船,您只需复制并粘贴以下代码(与接受的答案中列出的类不同,它可以防止NullPointerExceptions):
import java.util.Objects; public class Pair{ 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; } }
Map.Entry
这些内置类也是一个选项.两者都实现了Map.Entry
界面.
AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
Apache常见的lang3有Pair类和这个线程中提到的其他几个库什么相当于Java中的C++ Pair
匹配原始问题的要求的示例:
List> myPairs = new ArrayList >(); myPairs.add(Pair.of("val1", 11)); myPairs.add(Pair.of("val2", 17)); //... for(Pair 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[] 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坐标.
org.apache.commons commons-lang3 3.4
您可以编写一个通用的Pair 类,并在数组或列表中使用它.是的,您必须编写一个类,但您可以为所有类型重用相同的类,因此您只需要执行一次.
我打算问你是否不想只使用一个List
?但是,当然,JDK没有Pair <>类.但是快速谷歌在维基百科和forums.sun.com上找到了一个.干杯
您所描述的首选解决方案是一对列表(即列表).
要完成此任务,您需要创建一个Pair类,以便在您的集合中使用.这是一个有用的实用程序类,可以添加到您的代码库中.
Sun JDK中提供类似于典型Pair类的功能的最接近的类是AbstractMap.SimpleEntry.你可以使用这个类,而不是创建自己的Pair类,虽然你必须忍受一些尴尬的限制,我想大多数人都会对此不以为然,因为它并不是SimpleEntry的预期角色.例如,SimpleEntry没有"setKey()"方法,也没有默认构造函数,因此您可能会发现它太有限了.
请记住,集合旨在包含单一类型的元素.相关的实用程序接口(例如Map)实际上不是集合(即Map不实现Collection接口).一对不会实现Collection接口,但显然是构建更大数据结构的有用类.
扩展其他答案,通用不可变对应该有一个静态方法,以避免在调用构造函数时混乱代码:
class Pair{ final L left; final R right; public Pair(L left, R right) { this.left = left; this.right = right; } static Pair of(L left, R right){ return new Pair (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库在这些事情上如此稀疏,你必须使用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 SimpleEntrymyEntry = new SimpleEntry ("ID", "Text"); System.out.println("key: " + myEntry.getKey() + " value:" + myEntry.getValue()); System.out.println(); //======> List of Entries List > pairList = new ArrayList<>(); //-- Specify manually Entry firstButton = new SimpleEntry ("Red ", "Way out"); pairList.add(firstButton); //-- one liner: pairList.add(new SimpleEntry ("Gray", "Alternate route")); //Ananomous add. //-- Iterate over Entry array: for (Entry entr : pairList) { System.out.println("Button: " + entr.getKey() + " Label: " + entr.getValue()); }