консолидация избыточной информации в цикле

1

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

Ниже приведен пример данных в массиве outputarr:

key value
448 Ethanol
448 Alcohol
448 Alcohol
448 Ethanol
448 Ethanol
448 Alcohol
448 Ethanol
448 Alcohol
448 Ethyl alcohol  

Я хочу объединить это в массив со следующими данными:

key value
448 Ethanol; Alcohol; Ethyl alcohol

Таким образом, 9 строк в массиве объединяются в одну строку в arraylist. И значение в arraylist представляет собой конкатенированную строку "Ethanol; Alcohol; Ethyl alcohol". Но каждый цифровой ключ будет иметь различное количество значений, которые должны быть объединены таким образом, чтобы создать одну строку значений, в которой перечислены уникальные имена, которые были связаны с числовым ключом в массиве.

Вот код, который у меня есть до сих пор, как его отредактировать, чтобы он выполнил то, что я описал?

private static ArrayList<ArrayList<String>> twoDimArrList = new ArrayList<ArrayList<String>>();
public void someMethod(){
    int len = 1000;
    String[][] outputarr = new String[len][2];
    // ommitting code that populates outputarr because the next for loop is what needs help

    for(int r=0;r<len;r++){
        ArrayList<String> temp = new ArrayList<String>();
        if(outputarr[r][0]==outputarr[r+1][0]){
            if(outputarr[r][1].equalsIgnoreCase(outputarr[r+1][1])){
                temp.add(outputarr[r][0]);
                temp.add(outputarr[r][1]);
                twoDimArrList.add(temp);
                r+=1;
            }
        }
    }
}  
Теги:
arrays
arraylist

1 ответ

0

Существует несколько способов сделать это. Один из способов - использовать Map<Integer,Set<String>> для хранения данных, это сопоставит ключи с наборами значений.

Затем, когда вы будете читать свои данные:

Map<Integer,Set<String>> data = new HashMap<Integer,Set<String>>();

for each item in the file {

    Integer key = ...; // parsed 
    String value = ...; // parsed

    // retrieve set if it exists, create if it doesn't.
    Set<String> values = data.get(key);
    if (values == null) { 
        values = new HashSet<String>();
        data.put(key, values);
    }

    // add value to set
    values.add(value);

}

Если вы хотите сохранить повторяющиеся значения, используйте List вместо Set. Если вы хотите, например, подсчитать значения, подумайте о создании нового класса, содержащего значение и его счетчик (с соответствующими реализациями equals(), hashCode() и/или Comparable) и сохраните Set из тех, которые вы обновляете как значения читаются.

Вы могли бы представить и любое количество других подходов, но в конечном итоге все сводились бы к чему-то вроде выше: сопоставьте целочисленный идентификатор с коллекцией значений.

Вы также можете немного упростить свой код, если используете один из сторонних мультиплексов, которые по существу реализуют вышеописанные функции, такие как реализация Guava или Apache Commons; К сожалению, у JDK нет встроенных мультиплексов (см. раздел "Мультимаксы" здесь).


HashMap и HashSet не гарантируют какого-либо конкретного заказа, когда вы перебираете значения в контейнере. Если у вас есть особые требования к заказу, TreeMap/TreeSet будет TreeSet в порядке возрастания (естественный порядок, как определено Comparable/Comparator), а LinkedHashMap/LinkedHashSet сохранит порядок добавления элементов. Контейнеры выше могут быть заменены при необходимости.

Что касается итерации по данным, можно использовать стандартные методы и синтаксис, например:

for (Map.Entry<Integer,Set<String>> entry : data.entrySet()) {
    Integer key = entry.getKey();
    // ...
    for (String value : entry.getValue()) {
       // ...
    }
}

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

  • 3
    Лучше использовать Set вместо List
  • 0
    @SargeBorsch +1 Я как раз собирался отправить правку.
Показать ещё 10 комментариев

Ещё вопросы

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