我喜欢Java有一个Map,你可以在其中定义 Map 中每个条目的类型,例如 <String, Integer>
.
我正在寻找的是一种集合,其中集合中的每个元素都是一对值 . 对中的每个值都可以有自己的类型(如上面的String和Integer示例),它是在声明时定义的 .
该集合将保持其给定的顺序,并且不会将其中一个值视为唯一键(如在 Map 中) .
基本上我希望能够定义 <String,Integer>
类型的ARRAY或任何其他2种类型 .
我意识到我可以创建一个只有2个变量的类,但这看起来过于冗长 .
我也意识到我可以使用2D数组,但由于我需要使用不同的类型,我必须使它们成为OBJECT的数组,然后我必须一直投射 .
我只需要在集合中存储对,所以每个条目只需要两个值 . 没有走类路线,这样的事情是否存在?谢谢!
17 回答
Map.Entry
这些内置类也是一个选项 . 两者都实现Map.Entry接口 .
AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
扩展其他答案,通用不可变对应该有一个静态方法,以避免在调用构造函数时混乱代码:
如果您将静态方法命名为“of”或“pairOf”,则代码会变得流畅,因为您可以编写:
真正的耻辱是核心java库在这些事情上如此稀疏,你必须使用commons-lang或其他第三方来做这些基本的东西 . 升级到scala的另一个原因......
您所描述的首选解决方案是一对列表(即列表) .
要完成此任务,您需要创建一个Pair类,以便在您的集合中使用 . 这是一个有用的实用程序类,可以添加到您的代码库中 .
Sun JDK中提供类似于典型Pair类的功能的最接近的类是AbstractMap.SimpleEntry . 你可以使用这个类,而不是创建自己的Pair类,虽然你将不得不忍受一些尴尬的限制,我想大多数人会对此不以为然,因为它并不是SimpleEntry的预期角色 . 例如,SimpleEntry没有“setKey()”方法,也没有默认构造函数,因此您可能会发现它太有限了 .
请记住,集合旨在包含单一类型的元素 . 相关的实用程序接口(例如Map)实际上不是集合(即Map不实现Collection接口) . 一对不会实现Collection接口,但显然是构建更大数据结构的有用类 .
只需要创建一个类
然后创建元组的这些对象的列表
所以你也可以用同样的方式实现其他新的数据结构 .
Apache常见的lang3有Pair类和这个线程中提到的其他几个库What is the equivalent of the C++ Pair<L,R> in Java?
匹配原始问题的要求的示例:
那com.sun.tools.javac.util.Pair怎么样?
Java 9
在Java 9中,您只需编写:Map.entry(key, value)即可创建不可变对 .
Note: 此方法不允许键或值为null . 例如,如果要允许空值,则需要将其更改为:
Map.entry(key, Optional.ofNullable(value))
.Java 8
在Java 8中,您可以使用更通用的javafx.util.Pair来创建一个不可变的,可序列化的对 . 此类允许null键和null值 . (在Java 9中,此类包含在
javafx.base
模块中) . EDIT: As of Java 11, JavaFX has been decoupled from the JDK, so you'd need the additional maven artifact org.openjfx:javafx-base.Java 6
在Java 6及更高版本中,您可以使用更详细的AbstractMap.SimpleImmutableEntry表示不可变对,或者AbstractMap.SimpleEntry表示可以更改其值的对 . 这些类还允许null键和null值,并且是可序列化的 .
Android
如果您正在为Android编写,只需使用Pair.create(key, value)创建一个不可变对 .
Apache Commons
Apache Commons Lang提供了有用的Pair.of(key, value)来创建一个不可变的,可比较的,可序列化的对 .
Eclipse集合
如果您正在使用包含基元的对,Eclipse Collections提供了一些非常有效的原始对类,这将避免所有低效的自动装箱和自动拆箱 .
例如,您可以使用PrimitiveTuples.pair(int, int)创建IntIntPair,或使用PrimitiveTuples.pair(float, long)创建FloatLongPair .
龙目岛项目
使用Project Lombok,只需编写以下代码即可创建不可变对类:
Lombok将在生成的字节码中自动填写构造函数,getter,
equals()
,hashCode()
和toString()
方法 . 如果您想要静态工厂方法而不是构造函数(例如Pair.of(k, v)
),只需将注释更改为:@Value(staticConstructor = "of")
.否则
如果以上解决方案都没有浮动您的船,您只需复制并粘贴以下代码(与接受的答案中列出的类不同,它可以防止NullPointerExceptions):
您可以编写一个通用的Pair <A,B>类,并在数组或列表中使用它 . 是的,您必须编写一个类,但是您可以为所有类型重用相同的类,因此您只需要执行一次 .
在讨论键/值对时,我首先想到的是Properties Class,您可以将项目保存并加载到流/文件中 .
Apache Crunch 也有一个
Pair
类:http://crunch.apache.org/apidocs/0.5.0/org/apache/crunch/Pair.htmlAbstractMap.SimpleEntry
你很容易找到这个:
你怎么能填补它?
这简化为:
并且,在
createEntry
方法的帮助下,可以进一步减少详细程度:由于
ArrayList
不是最终的,因此可以将其子类化为公开of
方法(以及前面提到的createEntry
方法),从而导致语法简洁:"Apache Commons Lang 3"
Pair
类和相关的子类怎么样?ImmutablePair
是一个特定的子类,它不允许修改对中的值,但是还有其他实现具有不同的语义 . 如果需要,这些是Maven坐标 .这是基于JavaHelp4u的代码 .
不那么冗长,并说明如何在一行中完成以及如何循环 .
我的意思是,即使Java中没有
Pair
类,也有类似的东西:Map.Entry
Map.Entry Documentation
这是(简化了很多)
HashMap
,或实际上任何Map
存储 .您可以创建一个
Map
实例来存储您的值并获取条目集 . 你最终会得到Set<Map.Entry<K,V>>
,这实际上就是你想要的 .所以:
Pair类是那些“gimme”泛型示例之一,很容易自己编写 . 例如,我的头顶:
是的,它存在于网络的多个位置,具有不同程度的完整性和功能 . (我上面的例子是不可变的 . )
我打算问你是否不想只使用
List<Pair<T, U>>
?但是,当然,JDK没有Pair <>类 . 但是一个快速的谷歌在Wikipedia和forums.sun.com上找到了一个 . 干杯对于开发Android的任何人,您都可以使用android.util.Pair . :)