当前位置:  开发笔记 > 编程语言 > 正文

价值对的Java集合?(元组?)

如何解决《价值对的Java集合?(元组?)》经验,为你挑选了12个好方法。

我喜欢Java有一个Map,你可以在其中定义地图中每个条目的类型.

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

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

基本上我希望能够定义类型的ARRAY 或任何其他2种类型.

我意识到我可以创建一个只有2个变量的类,但这看起来过于冗长.

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

我只需要在集合中存储对,所以每个条目只需要两个值.如果没有上课路线,这样的事情会存在吗?谢谢!



1> 小智..:

AbstractMap.SimpleEntry

你很容易找到这个:

java.util.List> pairList= new java.util.ArrayList<>();

你怎么能填补它?

java.util.Map.Entry pair1=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);

这简化为:

Entry pair1=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);


仅供参考:建议`SimpleEntry`有一个兄弟类省略`setValue`方法是不可变的.因此名称为[`SimpleImmutableEntry`](https://docs.oracle.com/javase/8/docs/api/java/util/AbstractMap.SimpleImmutableEntry.html).
我不认为它是"标准的".`Entry`意味着是一个键值对,它就好了.但它作为一个真正的元组有弱点.例如,`SimpleEntry`中的`hashcode`实现只是xors元素的代码,所以``散列到与``相同的值.元组实现通常按字典顺序排序,但是`SimpleEntry`不实现`Comparable`.所以要小心......
这比自我实施更好.它易于实现的事实并不是每次实现它的借口.

2> Paul Brinkle..:

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

}

是的,这存在于网络的多个地方,具有不同程度的完整性和功能.(我上面的例子是不可变的.)


因此,如果我理解正确,推出一个简单的对类产生一个语法错误,一个subpar hashCode方法,空指针异常,没有compareTo方法,设计问题......人们仍然主张在Apache公共存在时推出这个类.如果您不想包含JAR但是停止重新发明轮子,请复制代码!
嗯......不,不会.这些字段标记为final,因此无法重新分配.并且它不是线程安全的,因为"左"和"右"可能是可变的.除非getLeft()/ getRight()返回防御性副本(在这种情况下无用),否则我看不出有什么大不了的.
你的意思是"容易自己写"?那是*糟糕的*软件工程.在MyPair和SomeoneElsesPair之间进行转换的N ^ 2适配器类是否也很容易在自己编写?
请注意,如果左右交换,hashCode()as-is会给出相同的值.也许:`long l = left.hashCode()*2654435761L;``return(int)l +(int)(l >>> 32)+ right.hashCode();`
我喜欢这个,但你怎么看左右字段公开?很明显,Pair类永远不会有任何逻辑关联,并且所有客户端都需要访问"left"和"right",那么为什么不轻松实现呢?
早先已经注意到NPE易感性.伙计们,这从来就不是真正的一对实现,记住,我把它潦草地写下来,甚至没有给它编译器; 它中的任何语法错误都可以轻易解决.如果你愿意的话,它可以很容易地用来取回并替换为第三方替代品.考虑到我经常在网上寻找已经存在的代码,我发现它想要的东西,并且不得不自己编写我自己的代码,是的,当你试图获得这个*是*良好的软件工程时完成的事情.
我真的会使用解决方案AbstractMap.SimpleEntry(参见下面的JavaHelp4U答案).无需实现自己的类.
请注意,如果left或right为null,则equals将抛出NPE.
如果`left`或`right`为`null`,这个`equals()`方法对于`NullPointerException`是可以接受的.使用`Objects.equals(this.left,pairo.getLeft())`(右边相同)来避免这种情况.

3> Hans Brende..:
Java 9+

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

注意:此方法不允许键或值为null.例如,如果要允许空值,则需要将其更改为:Map.entry(key, Optional.ofNullable(value)).


Java 8+

在Java 8中,您可以使用更通用的目的javafx.util.Pair来创建不可变的,可序列化的对.这个类允许null键和空值.(在Java 9中,此类包含在javafx.base模块中).编辑:从Java 11开始,JavaFX已经与JDK分离,所以你需要额外的maven工件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)创建IntIntPairPrimitiveTuples.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;
    }
}


然而,JavaFX仅限桌面,为非桌面环境(例如服务器)添加了不必要的依赖性.
Eclipse Collections还为对象提供了一个“对”接口,可以通过调用“ Tuples.pair(object1,object2)”来实例化该接口。http://www.eclipse.org/collections/javadoc/9.2.0/org/eclipse/collections/api/tuple/Pair.html
这感觉就像是最真实的Java风格的答案.所有可用的实现.非常彻底,非常感谢!

4> Johannes Wei..:
Map.Entry

这些内置类也是一个选项.两者都实现了Map.Entry界面.

AbstractMap.SimpleEntry

AbstractMap.SimpleImmutableEntry

Map.Entry接口的UML图,带有一对实现类


它们不仅仅是一种选择,它们是正确的答案.我认为有些人更喜欢重新发明轮子.

5> changed..:

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



6> XåpplI'-I0ll..:

对于任何开发Android的人,都可以使用android.util.Pair.:)



7> danidemi..:

那么"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
        



8> Dan Dyer..:

您可以编写一个通用的Pair 类,并在数组或列表中使用它.是的,您必须编写一个类,但您可以为所有类型重用相同的类,因此您只需要执行一次.



9> JMD..:

我打算问你是否不想只使用一个List>?但是,当然,JDK没有Pair <>类.但是快速谷歌在维基百科和forums.sun.com上找到了一个.干杯



10> 小智..:

您所描述的首选解决方案是一对列表(即列表).

要完成此任务,您需要创建一个Pair类,以便在您的集合中使用.这是一个有用的实用程序类,可以添加到您的代码库中.

Sun JDK中提供类似于典型Pair类的功能的最接近的类是AbstractMap.SimpleEntry.你可以使用这个类,而不是创建自己的Pair类,虽然你必须忍受一些尴尬的限制,我想大多数人都会对此不以为然,因为它并不是SimpleEntry的预期角色.例如,SimpleEntry没有"setKey()"方法,也没有默认构造函数,因此您可能会发现它太有限了.

请记住,集合旨在包含单一类型的元素.相关的实用程序接口(例如Map)实际上不是集合(即Map不实现Collection接口).一对不会实现Collection接口,但显然是构建更大数据结构的有用类.



11> simbo1905..:

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

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的另一个原因......



12> Leo Ufimtsev..:

这是基于JavaHelp4u的代码.

更简洁,并显示如何在一行中如何做以及如何循环事物.

//======>  Imports
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

//======>  Single Entry
SimpleEntry myEntry = 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());
}

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有