Как сохранить массив пар в java?

Я новичок в java, я хочу сохранить массив пары двойников. Мой код выглядит так:

import java.util.ArrayList;
import java.util.Map.Entry;

List<Entry<Double, Double>> values = new ArrayList<>();
Entry<Double, Double> pair;
// set pair values:
// pair.setKey(0.5); // this method does not exists
// pair.setValue(3.6);
values.add(pair);

как инициализировать переменную pair ? Есть ли лучшая структура для хранения моего массива пар двойников ?

8 ответов


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

public class MyPair
{
    private final Double key;
    private final Double value;

    public MyPair(Double aKey, Double aValue)
    {
        key   = aKey;
        value = aValue;
    }

    public Double key()   { return key; }
    public Double value() { return value; }
}

см. этот ответ по причинам, почему a Pair не существует в Java: что такое эквивалент пары C++ в Java?


вы не хотите использовать запись, это интерфейс, а не класс. Этот интерфейс используется реализациями Set при вызове entrySet () в классе, который реализует Map. Это в основном позволяет вам манипулировать реализованной картой, как если бы она была набором.

то, что вы сделали бы (но не можете), это. Если вы попытаетесь сделать это, вы увидите ошибку компилятора по строкам "не удается создать экземпляр карты типов.Вступление." Это потому, что карта.Запись-это интерфейс, а не класс. Интерфейс не содержит любой реальный код, поэтому здесь нет реального конструктора для запуска.

Entry<Double, Double> pair = new Entry<Double, Double>();

Если вы посмотрите на приведенные ниже документы, вы можете ясно видеть вверху, что это "карта интерфейса".Запись " что означает, что это интерфейс. http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.Entry.html

что вы должны сделать вместо того, чтобы пытаться создать экземпляр интерфейса, что невозможно, это создать свой собственный класс под названием Pair. Что-то вроде этого. Не забудьте изменить пакет, если вы используете код ниже.

package org.mike.test;

public class Pair {
    private double x = 0.0;
    private double y = 0.0;

    public Pair(double x, double y)
    {
        this.x = x;
        this.y = y;
    }

    public Pair()
    {

    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }


}

после написания класса пары ваш код теперь будет выглядеть так.

package org.mike.test;

import java.util.ArrayList;
import org.mike.test.Pair; //You don't need this if the Pair class is in the same package as the class using it

public class tester {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ArrayList<Pair> values = new ArrayList<Pair>();
        Pair pair = new Pair();
        // set pair values:
        pair.setY(3.6);
        pair.setX(3.6);
        values.add(pair);
    }

}

Не могли бы вы просто использовать

public class MyClass<A,B> extends ArrayList{
private A first;
private B second;
public MyClass(A first, B second){
super();
this.first = first;
this.second = second;}
}

а затем добавьте некоторую форму метода add вместе с первым и вторым методом доступа и мутатора? Я вроде как новичок в программировании, но этот способ, похоже, может работать и быть доступен для вещей, отличных от DOUBLE (в случае, если вы хотите использовать другие типы, такие как Integer или даже String).


вы можете использовать карту, чтобы решить эту проблему.


Is Entry класс Вас определили? Вы создаете его с помощью new.

Entry<Double, Double> pair = new Entry<Double, Double>(d1, d2);

примечание Я предполагаю, что вы определили конструктор, который принимает 2 двойника, и у вас есть ссылки на d1 и d2.

Я предлагаю вам не использовать Map.Entry класса. Семантика для этого класса такова, что значения являются ключом и значением, соответствующим способу работы карт.


Если у вас есть доступ к классу Entry, вы можете создать конструктор, который принимает ключ и значение в качестве параметров.

Entry<Double, Double> pair = new Entry<Double, Double>(0.5, 3.6);
values.add(pair);

на Map.Entry тип, который вы пытаетесь использовать, является просто интерфейсом и поэтому не может быть создан. Если вы хотите (mis)использовать внутренние типы Map, то б Map.Entry реализация HashEntry был бы вариант.

однако гораздо лучше реализовать собственный тип пары. Или использовать карту вместо массива, если это вам нужно.


другой подход и, вероятно, самый эффективный способ хранения и массива двойных пар-использовать один массив двойников и использовать (2*i) и (2*i + 1) в качестве схемы индексирования. Кроме того, вы получаете преимущество, что массив будет инициализирован для всех 0 при его создании, никаких дополнительных шагов не требуется. К сожалению, есть немного дополнительных накладных расходов на кодирование для реализации add () и remove (), но удивительно, что это, вероятно, меньше, чем создание собственного класса контейнера для пара.

class MyClass {
    double[] values;
    int count;

    MyClass(int initialCapacity) {
        values = new double[initialCapacity*2];
    }

    // adding a pair
    void addPair(double x, double y) {
        if (count*2 >= values.length) {
            values = Arrays.copyOf(values, values.length*2);
        }
        values[count*2] = x;
        values[count*2 + 1] = y;
        count++;
    }

    void remove(int index) {
        if (index >= count) throw new IndexOutOfBoundsException();

        if (index < --count) {
            System.arraycopy(values, (index+1)*2, values, index*2, (count - index) * 2);
        }
    }

    int size() { return count; }

    // both these should check that index < count.
    double getX(int index) { return values[index*2]; }
    double getY(int index) { return values[index*2 + 1]; }

    void exampleIteration() {
        // getX/Y accessors are examples of how to get
        // the values, but it will be more efficient
        // in most cases to just access the array
        // array directly as so...
        for (int i=0 ; i<count ; ++i) {
            System.out.printf("%d: (%f,%f)%n", i, values[i*2], values[i*2+1]);
        }
    }
}