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

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

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

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

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

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

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


当前回答

我的意思是,尽管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
}

其他回答

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());
}

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

这是基于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());
}

Java 9 +

在Java 9中,您可以简单地编写:Map。条目(关键字,值) 创建一个不可变的pair。

注意:此方法不允许键或值为空。例如,如果您希望允许空值,则需要将其更改为:Map。条目(关键Optional.ofNullable(值))。


Java 8 +

在Java 8中,您可以使用更通用的javafx.util.Pair来创建不可变的、可序列化的pair。这个类允许空键和空值。(在Java 9中,该类包含在javafx中。基础模块)。编辑:从Java 11开始,JavaFX已经从JDK中解耦了,所以您需要额外的maven构件org.openjfx: JavaFX -base。


Java 6 +

在Java 6及更高版本中,您可以使用更详细的AbstractMap。不可变对或AbstractMap的SimpleImmutableEntry。SimpleEntry的值可以被更改。这些类还允许空键和空值,并且是可序列化的。


安卓

如果你正在为Android编写程序,那就使用Pair。Create (key, value)创建一个不可变的pair。


Apache Commons

Apache Commons Lang提供了有用的Pair。(key, value)来创建不可变的、可比较的、可序列化的对。


Eclipse集合

如果您正在使用包含原语的对,Eclipse Collections提供了一些非常有效的原语对类,可以避免所有低效的自动装箱和自动拆箱。

例如,您可以使用PrimitiveTuples。pair(int, int)来创建一个IntIntPair或PrimitiveTuples。(float, long)来创建一个FloatLongPair。


手卷的实现

从Java 16开始,记录已经脱离预览状态,所以您现在可以执行以下操作:

public record Pair<K, V>(K key, V value) {
    public static <K, V> Pair<K, V> of(K key, V value) {
        return new Pair<>(key, value);
    }
}

上面的实现在未来将有很大的优势,因为它将允许您进行记录解构。

在Java 16之前,您可以使用Project Lombok实现相同的语义:

@Value(staticConstructor = "of")
public class Pair<K, V> {
    K key;
    V value;
}

或者,使用下面的冗长(与已接受的答案中列出的类不同,它可以防止nullpointerexception,并且具有与Records1相同的健壮的hashCode()实现):

import java.util.Objects;

public class Pair<K, V> {

    public final K key;
    public final V value;

    private Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public static <K, V> Pair<K, V> of(K key, V value) {
        return new Pair<>(key, 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;
    }
}

1在OpenJDK 17上测试

“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是一个特定的子类,它不允许修改pair中的值,但是还有其他具有不同语义的实现。这些是Maven的坐标,如果你需要的话。

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