Коллекция Java пар значений? (кортежи?)



мне нравится, как Java имеет карту, где вы можете определить типы каждой записи на карте, например <String, Integer>.



то, что я ищу, - это тип коллекции, где каждый элемент в коллекции-это пара значений. Каждое значение в паре может иметь свой собственный тип (как строка и целое число пример выше), который определяется во время объявления.



коллекция будет поддерживать заданный порядок и не будет рассматривать одно из значений как уникальный ключ (как на карте).



по существу я хочу иметь возможность определить массив типа <String,Integer> или любые другие 2 типов.



Я понимаю, что я могу сделать класс только с двумя переменными в нем, но это кажется слишком многословным.



Я также понимаю, что я мог бы использовать 2D-массив, но из-за разных типов, которые мне нужно использовать, мне пришлось бы сделать их массивами объектов, а затем мне пришлось бы все время бросать.



мне нужно только хранить пары в коллекции, поэтому я только нужно два значения на запись. Существует ли что-то подобное без прохождения маршрута класса? Спасибо!

2752   17  

17 ответов:

класс Pair является одним из тех примеров" gimme " generics, которые достаточно легко написать самостоятельно. Например, с верхней части моей головы:

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 не является окончательным, он может быть разделен на подклассы, чтобы разоблачить of метод (и вышеупомянутый createEntry способ), в результате чего синтаксически лаконично:

TupleList<java.util.Map.Entry<String,Integer>> pair = new TupleList<>();
pair.of("Not Unique key1", 1);
pair.of("Not Unique key2", 2);

Java 9+

в Java 9, вы можете просто написать: Map.entry(key, value) чтобы создать неизменяемую пару.

Примечание: этот метод не позволяет ключам или значениям быть null. Если вы хотите разрешить значения null, например, вы хотите изменить это на:Map.entry(key, Optional.ofNullable(value)).


Java 8+

в Java 8, вы можете использовать более общие цели javafx.util.Pair для создания неизменяемой, сериализуемой пары. Этот класс тут разрешить нулевые ключи и значения null. (В Java 9, этот класс включен в javafx.base модуль). EDIT: начиная с Java 11, JavaFX был отделен от JDK, поэтому вам понадобится дополнительная организация артефактов maven.openjfx: javafx-base.


Java 6+

в Java 6 и выше, вы можете использовать более многословным AbstractMap.SimpleImmutableEntry для неизменяемой пары, или AbstractMap.SimpleEntry для пары, значение которого может быть изменено. Эти занятия также позволяют нулевые ключи и значения NULL, и являются сериализуемыми.


Android

если вы пишете для Android, просто используйте Pair.create(key, value) для создания неизменяемой пары.


Apache Commons

Apache Commons Lang обеспечивает полезным Pair.of(key, value) для создания неизменяемой, сопоставимой, сериализуемой пары.


Коллекции Eclipse

если вы используете пары, содержащие примитивы, Коллекции Eclipse предоставляет некоторые очень эффективные классы примитивных пар, которые позволят избежать всех неэффективных авто-бокса и авто-распаковки.

например, вы можете использовать PrimitiveTuples.pair(int, int) создать IntIntPair или PrimitiveTuples.pair(float, long) создать FloatLongPair.


иначе

если ни одно из вышеуказанных решений не плавает на вашей лодке, вы можете просто скопируйте и вставьте следующий код (который, в отличие от класса, указанного в принятом ответе, защищает от 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 common lang3 имеет класс Pair и несколько других библиотек, упомянутых в этом потоке что эквивалентно паре C++ в Java?

пример соответствия требованию из вашего исходного вопроса:

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.утиль.Пара. :)

как насчет "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>

Я собирался спросить, не хотите ли вы просто использовать List<Pair<T, U>>? но тогда, конечно, JDK не имеет класса Pair. Но быстрый Google нашел один на обе Википедия и forums.sun.com. Ура

предпочтительным решением, как вы описали, является список пар (т. е. список).

для этого вы должны создать класс Pair для использования в вашей коллекции. Это полезный служебный класс для добавления в базу кода.

ближайший класс В Sun JDK, обеспечивающий функциональность, подобную типичному классу пары, является AbstractMap.Все просто. Вы можете использовать этот класс, а не создавать свой собственный класс пар, хотя вам придется жить с некоторыми неудобными ограничения, и я думаю, что большинство людей будут хмуриться на это, как не совсем предполагаемая роль SimpleEntry. Например, SimpleEntry не имеет метода "setKey ()" и конструктора по умолчанию, поэтому вы можете найти его слишком ограниченным.

имейте в виду, что коллекции предназначены для хранения элементов одного типа. Связанные служебные интерфейсы, такие как Map, на самом деле не являются коллекциями (т. е. Map не реализует интерфейс коллекции). Пара также не будет реализовывать интерфейс коллекции но, очевидно, это полезный класс для построения больших структур данных.

расширение других ответов общая неизменяемая пара должна иметь статический метод, чтобы избежать загромождения вашего кода вызовом конструктора:

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 x.y.Pair.pairOf

это настоящий позор, что основные библиотеки java настолько редки на таких вещах, что вам нужно использовать commons-lang или другие третьи стороны, чтобы делать такие базовые вещи. еще одна причина для обновления до скала...

это основано на коде 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>();

таким образом, вы также можете выполнять другие новые структуры данных таким же образом.

Я имею в виду, хотя нет Pair класс в Java есть что-то довольно похожее: 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.солнце.инструменты.и javac.утиль.Пара?

Первое, что я думаю, когда говорю о парах ключ / значение-это Properties Класс где вы можете сохранять и Загружать элементы в поток/файл.

Comments

    Ничего не найдено.