Сортировка arraylist по отношению к другому это другой arraylist в Java

1

Предупреждения: Эти примеры - просто примеры. Не тот же мой код, так что не думайте, что он дублирует или плохой вопрос и голосует!

Это название может быть немного запутанным, извините за это. Здесь моя проблема;

У меня есть два арраиста. Один из них берет строку и одно целое. Позвольте мне проиллюстрировать это

arrList1 = {"apple", "strawberry", "banana", "watermelon"};
arrList2 = {   60,        90,         77 ,       160};

arrList2 магазин сколько фруктов в arrList1 в одном и том же номере индекса. Например, есть 60 яблок, 90 клубники, 77 бананов, 160 арбуз.

Кроме того, у меня есть еще два Arraylist, как и выше;

arrList3 = { "strawberry", "watermelon", "apple", "banana" };
arrList4 = {      45,          40 ,         10 ,     11 };

arrList1 и arrList3 имеют одну и ту же строку, но разные номера индексов. Теперь я хочу напечатать, как делить число arrList2 на число arrList1 и напечатать объекты по порядку количества. Позвольте мне проиллюстрировать это;

apple = 60/10 = 6
strawberry = 90/45 = 2
banana =  77/11 = 7
watermelon = 160/40 = 4

Мы разделили и получили некоторые цифры и распечатали консоль, упорядоченную по суммам;

Banana  // first because we got 7 
Apple   // second because we got 6  and etc
Watermelon 
Strawberry

Итак, как я это делаю эффективно?


Чтобы быть ясным, здесь есть два вопроса:

  1. Как эффективно выполнять поиск каждого фрукта в каждой паре массивов?
  2. Как эффективно сортировать результаты деления значений соответствующих записей?
  • 1
    Вы можете просто сделать один объектный фрукт и иметь их как свойства
  • 0
    Может быть, я могу, но переделка программы занимает много времени
Показать ещё 8 комментариев
Теги:

4 ответа

3

У вас, кажется, есть массивы, а не ArrayList (s). Затем вы должны создать класс Fruit который реализует Comparable<Fruit>. Он должен иметь два поля, сумму и имя. Затем вы можете использовать Map<String, Integer> для выполнения вашего разделения и, наконец, построить и отсортировать List Fruit (ы). Что-то вроде этого,

public class Fruit implements Comparable<Fruit> {
    private final String name;
    private int amount;

    public Fruit(String name, int amount) {
        super();
        this.name = (name != null) ? name.trim() : "";
        setAmount(amount);
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public int getAmount() {
        return amount;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof Fruit) {
            Fruit that = (Fruit) o;
            return this.name.equals(that.name);
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("%s = %d", name, amount);
    }

    @Override
    public int compareTo(Fruit o) {
        return Integer.valueOf(o.amount).compareTo(amount);
    }

    @Override
    public int hashCode() {
        return this.name.hashCode();
    }

    public static void main(String[] args) {
        String[] arrList1 = { "apple", "strawberry", "banana", "watermelon" };
        int[] arrList2 = { 60, 90, 77, 160 };
        String[] arrList3 = { "strawberry", "watermelon", "apple", "banana" };
        int[] arrList4 = { 45, 40, 10, 11 };
        Map<String, Integer> map = new TreeMap<>();
        for (int i = 0; i < arrList1.length; i++) {
            map.put(arrList1[i], arrList2[i]);
        }
        List<Fruit> al = new ArrayList<>();
        for (int i = 0; i < arrList3.length; i++) {
            String key = arrList3[i];
            int val = map.get(key) / arrList4[i];
            al.add(new Fruit(key, val));
        }
        Collections.sort(al);
        System.out.println(al);
    }
}

Какой (когда я запускаю его здесь) выходы,

[banana = 7, apple = 6, watermelon = 4, strawberry = 2]
  • 0
    hashCode() зависит от изменяемого значения?
  • 0
    @jdphenix Да, это должно было быть неизменным. Ред. Спасибо!
Показать ещё 2 комментария
0

Итак, как я это делаю эффективно?

Не используйте отдельные массивы. Инкапсулируйте нужные данные в POJO (обычные старые объекты Java) и используйте API коллекций

Но, не используя List или Map, вам нужно построить, по крайней мере, еще два массива (или, по крайней мере, я это сделал))...

Первые будут содержать результаты расчётов. Для этого вам нужно найти способ сопоставления индексов из arrList1 в arrList3, например...

Это найдет индекс данного значения в данном массиве или возвращает -1 если он не найден...

public static int find(String value, String[] list) {

    int matchIndex = -1;
    for (int index = 0; index < list.length; index++) {
        if (list[index].equals(value)) {
            matchIndex = index;
            break;
        }
    }
    return matchIndex;

}

Затем нам нужно вычислить результаты...

int[] results = new int[arrList1.length];
for (int index = 0; index < arrList1.length; index++) {
    String v1 = arrList1[index];
    int v2 = arrList2[index];
    int subIndex = find(v1, arrList3);
    if (subIndex != -1) {
        int v4 = arrList4[subIndex];
        results[index] = (v2 / v4);
        System.out.println(v1 + " = " + v2 + " / " + v4 + " = " + results[index]);
    }
}

Это приведет к выходу...

apple = 60 / 10 = 6
strawberry = 90 / 45 = 2
banana = 77 / 11 = 7
watermelon = 160 / 40 = 4

И сохраните результаты расчетов в массиве results...

Теперь пришла интересная часть... Мы могли сортировать ВСЕ массивы, но это мне кажется бесполезным, или мы могли бы создать массив "прокси", отдельные элементы которого указывали на индекс в других массивах. Это будет представлять собой "виртуальный" сортированный вид всех массивов...

int[] proxy = new int[arrList1.length];
for (int index = 0; index < proxy.length; index++) {
    proxy[index] = index;
}

for (int n = 0; n < results.length; n++) {
    for (int m = 0; m < results.length - 1 - n; m++) {
        if ((results[proxy[m + 1]] - (results[proxy[m]])) > 0) {
            int index = proxy[m];
            proxy[m] = proxy[m + 1];
            proxy[m + 1] = index;
        }
    }
}

Это означает, что proxy[0] будет удерживать индекс первого элемента при сортировке.

И если мы используем это для печати результатов...

for (int index : proxy) {

    System.out.println(arrList1[index] + " = " + results[index]);

}

У нас есть что-то вроде...

banana = 7
apple = 6
watermelon = 4
strawberry = 2

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

Если вам нужен список в отсортированном порядке, вы можете легко создавать новые массивы и применять значения соответственно (как, например, при печати результатов)

Сказав это все. POJO, которые могли бы удерживать различные свойства, и List и/или отсортированную Map были бы значительно проще: P

  • 0
    Серьезно ... почему отрицание? Конечно, он не использует API Collections , но демонстрирует концепции, которые OP может использовать в своем существующем коде, основываясь на доступной информации. Просветите меня своими проблемами, чтобы мы могли улучшить ответ ...
0

Вы можете использовать карты:

Map<String, Integer> fruit1 = new HashMap<String, Integer>();
Map<String, Integer> fruit2 = new HashMap<String, Integer>();

тогда:

fruit1.put("apple", 60);
fruit2.put("apple", 10);

И наконец:

System.out.println(fruit1.get("apple")/fruit2.get("apple"));

EDIT: для его сортировки используйте другую карту - на этот раз TreeMap, которая поддерживает отсортированный порядок (будет ключ):

Map<Integer, String> results = new TreeMap<Integer, String>();
results.add(fruit1.get("apple")/fruit2.get("apple"), "apple");
// add more...

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

for(Map.Entry<Integer,String> entry : results.entrySet()) {
    System.out.println(entry.getValue() + ": " + entry.getKey());
}

Это напечатает:

apple: 6
//and so on...
  • 0
    Сэр, у меня много элементов, я не могу поставить такой элемент
  • 0
    Я не думаю, что .getValue() необходим, поскольку Java автоматически распаковывает Integer s.
Показать ещё 11 комментариев
0
public class Main {

    public static void main(String[] args) {

        String[] arrList1 = { "apple", "strawberry", "banana", "watermelon" };
        Integer[] arrList2 = { 60, 90, 77, 160 };

        String[] arrList3 = { "strawberry", "watermelon", "apple", "banana" };
        Integer[] arrList4 = { 45, 40, 10, 11 };

        HashMap<String, Integer> result = new HashMap<>();

        for (int i = 0; i < arrList1.length; i++) {
            for (int j = 0; j < arrList3.length; j++) {
                if (arrList1[i].contains(arrList3[j])) {
                    result.put(arrList1[i], arrList2[i] + arrList4[j]);
                }
            }
        }

        LinkedHashMap sorted = sortHashMap(result);
        Set<String> keys = sorted.keySet();
        for(String k:keys){
            System.out.println(k+" -- "+sorted.get(k));
        }
        System.out.println("End");

    }

    public static LinkedHashMap sortHashMap(HashMap passedMap) {
        List mapKeys = new ArrayList(passedMap.keySet());
        List mapValues = new ArrayList(passedMap.values());
        Collections.sort(mapValues);
        Collections.sort(mapKeys);

        LinkedHashMap sortedMap = new LinkedHashMap();

        Iterator valueIt = mapValues.iterator();
        while (valueIt.hasNext()) {
            Object val = valueIt.next();
            Iterator keyIt = mapKeys.iterator();

            while (keyIt.hasNext()) {
                Object key = keyIt.next();
                String comp1 = passedMap.get(key).toString();
                String comp2 = val.toString();

                if (comp1.equals(comp2)) {
                    passedMap.remove(key);
                    mapKeys.remove(key);
                    sortedMap.put((String) key, (Integer) val);
                    break;
                }

            }

        }
        return sortedMap;
    }

}

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

  • 0
    Вы получите лучший результат с TreeMap ... но вам придется поменять ключ / значение
  • 0
    Да, верно. Есть много способов решить эту проблему :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню