Я хочу отсортировать два параллельных массива, один из которых имеет строку, а другой — двойные типы данных

#java #arrays

#java #массивы

Вопрос:

Я относительно новичок в области программирования и хотел бы, чтобы вы помогли мне с сортировкой этих массивов. Идея состоит в том, чтобы отобразить пункт меню в текстовой области и отсортировать элементы по имени. Параллельные массивы содержат продукты питания, а другой — цены.

 String[] items  = {"Gatspy", "Coffee", "Chicken", "Mango Juice"};
double[] prices = {8.99, 23.50, 29.90, 7.50};
  

Комментарии:

1. Каждый 4-й рабочий день сюда приходят люди, желающие отсортировать параллельные массивы. Каждый раз 6 человек вскакивают и говорят: используйте лучшую структуру данных. (a) Почему это происходит? Этому учат в колледже или что-то в этом роде (б) должны ли мы назначить один из них в качестве часто задаваемых вопросов?

2. Это справедливое замечание — я полагаю, что на самом деле это, вероятно, связано с отсутствием понимания инкапсуляции данных. Поэтому, вероятно, где-то в FAQ следует подчеркнуть, что «прежде чем что-либо делать, подумайте об инкапсуляции данных и о том, насколько хорошо вы спроектировали свои структуры данных». Иногда есть причины, по которым можно использовать параллельные массивы, но это, конечно, не похоже на один из таких случаев.

Ответ №1:

Или как насчет инкапсуляции названия товара и цены в классе, затем иметь один массив экземпляров этого класса и использовать Comparator для их сортировки? Например.

 public class Item {
private String name;
private double price;
...
//getters and setters for name and price
}

...

Item []items = { new Item("Gatspy", 8.99), .... };

...

class ItemComparator implements Comparator {
 public int compare( Object o1, Object o2 ) {
  Item i1 = (Item)o1;
  Item i2 = (Item)o2;
  return i1.getName().compareTo(i2.getName());
 }
}

...

Arrays.sort( items, new ItemComparator() );
  

Ответ №2:

Во-первых, не используйте массивы, используйте Map . В вашем случае используйте a TreeMap , он сортируется по его ключам.

 Map<String, Double> map = new TreeMap<String, Double>();
map.put("Gatspy", 8.99);
// put the other items
  

Теперь выполните итерацию по записям:

 for(Map.Entry<String, Double> entry : map.entrySet()){
    System.out.println("<option value="" 
                         entry.getValue() 
                         "">" 
                         entry.getKey() 
                         "</option>");
}
  

Ссылка: Учебное пособие по Java > Отслеживание коллекций > Интерфейс карты

Комментарии:

1. в общем случае a Map не будет работать в случае дубликатов, таких как {"Coffee", "Chicken", "Coffee"} и {5.99, 6.0, 2.35}

2. @MarcoS, очевидно. Но мы говорим о меню, и оно никогда не должно содержать повторяющихся элементов!

Ответ №3:

Вы должны использовать объекты:

 public class Item {
    private String name;
    private double price; // you shouldn't use doubles for money, but this is unrelated

    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return this.name;
    }

    public double getPrice() {
        return this.price;
    }
}
  

Тогда у вас может быть массив (или список) элементов :

 private Item[] items = new Item[] {new Item("Gtaspy", 8.99), ...};
  

и вы можете отсортировать этот массив с помощью Arrays.sort() (или Collections.sort(), если вы используете список вместо массива).

Прочитайте руководство по Java по коллекциям для получения более подробной информации.

Комментарии:

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

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

3. спасибо за вашу помощь, ребята, но наш лектор настоял на том, чтобы мы использовали параллельные массивы и отображали их в JList. Итак, когда теперь мне удалось отобразить массивы элементов строкового типа данных в JList, но я не могу отобразить массив цен двойного типа данных. вот как я это сделал: String [] items = {«Сырный бургер», «Гэтсби», «Капучино», «Горячие крылышки», «Рыба с жареным картофелем», «Кофе», «Кальмары»}; Arrays.sort(меню); foodList = новый JList (элементы);//foodList — это объект JList

Ответ №4:

Возможный подход может быть таким же, как реализован в этой библиотеке math3: org.apache.commons.math3.util.MathArrays#sortInPlace

 /**
 * Sort an array in place and perform the same reordering of entries on
 * other arrays.  This method works the same as the other
 * {@link #sortInPlace(double[], double[][]) sortInPlace} method, but
 * allows the order of the sort to be provided in the {@code dir}
 * parameter.
 *
 * @param x Array to be sorted and used as a pattern for permutation
 * of the other arrays.
 * @param dir Order direction.
 * @param yList Set of arrays whose permutations of entries will follow
 * those performed on {@code x}.
 * @throws DimensionMismatchException if any {@code y} is not the same
 * size as {@code x}.
 * @throws NullArgumentException if {@code x} or any {@code y} is null
 * @since 3.0
 */
public static void sortInPlace(double[] x,
                               final OrderDirection dir,
                               double[] ... yList)
    throws NullArgumentException, DimensionMismatchException {
    if (x == null) {
        throw new NullArgumentException();
    }

    final int len = x.length;
    final List<Pair<Double, double[]>> list
        = new ArrayList<Pair<Double, double[]>>(len);

    final int yListLen = yList.length;
    for (int i = 0; i < len; i  ) {
        final double[] yValues = new double[yListLen];
        for (int j = 0; j < yListLen; j  ) {
            double[] y = yList[j];
            if (y == null) {
                throw new NullArgumentException();
            }
            if (y.length != len) {
                throw new DimensionMismatchException(y.length, len);
            }
            yValues[j] = y[i];
        }
        list.add(new Pair<Double, double[]>(x[i], yValues));
    }

    final Comparator<Pair<Double, double[]>> comp
        = new Comparator<Pair<Double, double[]>>() {
        public int compare(Pair<Double, double[]> o1,
                           Pair<Double, double[]> o2) {
            int val;
            switch (dir) {
            case INCREASING:
                val = o1.getKey().compareTo(o2.getKey());
            break;
            case DECREASING:
                val = o2.getKey().compareTo(o1.getKey());
            break;
            default:
                // Should never happen.
                throw new MathInternalError();
            }
            return val;
        }
    };

    Collections.sort(list, comp);

    for (int i = 0; i < len; i  ) {
        final Pair<Double, double[]> e = list.get(i);
        x[i] = e.getKey();
        final double[] yValues = e.getValue();
        for (int j = 0; j < yListLen; j  ) {
            yList[j][i] = yValues[j];
        }
    }
}