как сравнить два HashMap <String, List <String >>

Я хочу сравнить данные, прочитанные из файла excel (ключ – столбец 1, значение – столбец 2), который помещается в HashMap с данными, полученными из SQL-запроса. Сначала я сделал это с помощью HashMap <String, String>, потому что мне пришлось сравнивать только пары <key, value>, но теперь мне нужно сравнить <key, list>, и я немного застрял. Вот мой код для чтения файла xls:

public class ReadExcel { HashMap<String, List<String>> result = new HashMap<String, List<String>>(); public HashMap<String, List<String>> process() { try { result.clear(); FileInputStream file = new FileInputStream(new File("C:/some.xlsx")); //Create Workbook instance holding reference to .xlsx file XSSFWorkbook workbook = new XSSFWorkbook(file); //Get first/desired sheet from the workbook XSSFSheet sheet = workbook.getSheetAt(0); //Iterate through each rows one by one Iterator<Row> rowIterator = sheet.iterator(); while (rowIterator.hasNext()) { List<String> xlsList = new ArrayList<String>(); Row row = rowIterator.next(); Cell cell = row.getCell(1); Cell cell2 = row.getCell(2); String key =""; String value=""; xlsList.clear(); switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC: key = getStringCellValue(cell); value = getNumericCellValue(cell2); break; case Cell.CELL_TYPE_STRING: key = getStringCellValue(cell); value = getStringCellValue(cell2); break; } xlsList.add(value); result.put(key, xlsList); } } } 

Например, в моем файле excel для

 row 1: column 1 = car, column 2 = blue row 2: column 1 = car, column 2 = yellow. 

Когда я запускаю excel reader, он ставит значения «синий, желтый» очень хорошо под «автомобильным» ключом в HashMap. Когда у меня есть, например:

 row 1: column 1 = car, column 2 = blue row 2: column 1 = car, column 2 = yellow row 3: column 1 = year, column 2 = 1990 row 4: column 1 = year, column 2 = 1999 

он отображает только: car=[yellow], year=[1999] . Он принимает только последние значения, это отлично работает, если не для дубликатов ключей.

Первый вопрос: как я могу сделать это лучше? если я получаю одинаковые ключи в строке 1, чтобы взять ключ только один раз и сохранить все значения из строки 2, если ключ из строки 1 одинаковый?

Вот мой код для извлечения данных из базы данных SQL:

 public class DB { HashMap<String, List<String>> result = new HashMap<String, List<String>>(); public HashMap<String, List<String>> process() { result.clear(); Connection conn = null; Statement stmt = null; List<String> carColour = new ArrayList<String>(); try { Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection(DB_URL, USER, PASS); stmt = conn.createStatement(); String sql1 = "SOME SQL SELECT STATEMENT THAT RETURNS 2 or more lines, by that i mean "car" has 2 values or more"; ResultSet rs = stmt.executeQuery(sql1); while(rs.next()){ carColour.add(rs.getString("colour")); // i select the column "colour" result.put("car", carColour); // i put "car" as key, and "blue" and "yellow" as values ................................... } } catch... } в public class DB { HashMap<String, List<String>> result = new HashMap<String, List<String>>(); public HashMap<String, List<String>> process() { result.clear(); Connection conn = null; Statement stmt = null; List<String> carColour = new ArrayList<String>(); try { Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection(DB_URL, USER, PASS); stmt = conn.createStatement(); String sql1 = "SOME SQL SELECT STATEMENT THAT RETURNS 2 or more lines, by that i mean "car" has 2 values or more"; ResultSet rs = stmt.executeQuery(sql1); while(rs.next()){ carColour.add(rs.getString("colour")); // i select the column "colour" result.put("car", carColour); // i put "car" as key, and "blue" and "yellow" as values ................................... } } catch... } 

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

Второй вопрос: как я могу сделать это проще, чем создавать 20 списков? (Используйте тот же список, возможно, и list.clear (); он?) (Здесь это зависит, потому что, если я получил 30 столбцов, и мне нужно всего 20, я могу getString («column») и удалить те, которые мне не нужны, но как?

Вот код для сравнения:

 final Map<String, Boolean> comparisonResult = compareEntries(dbResult, xlsResult); for(final Entry<String, Boolean> entry : comparisonResult.entrySet()){ if (entry.getValue() == false){ System.out.println("------------------------------------------------------------------------"); System.out.println("| Comparison FAILED | Value not matching! Column name --> " + entry.getKey() + " |"); } } System.out.println("------------------------------------------------------------------------"); System.out.println("DB consistency check finished."); 

………………………………………….. …………………………

 public static <K extends Comparable<? super K>, V> Map<K, Boolean> compareEntries(final Map<K, V> dbResult, final Map<K, V> xlsResult){ final Collection<K> allKeys = new HashSet<K>(); allKeys.addAll(dbResult.keySet()); allKeys.addAll(xlsResult.keySet()); final Map<K, Boolean> result = new TreeMap<K, Boolean>(); for(final K key : allKeys){ result.put(key, dbResult.containsKey(key) == xlsResult.containsKey(key) && Boolean.valueOf(equal(dbResult.get(key), xlsResult.get(key)))); } return result; } private static boolean equal(final Object obj1, final Object obj2){ return obj1 == obj2 || (obj1 != null && obj1.equals(obj2)); } 

Последний вопрос: как я могу улучшить код для сравнения двух HashMap (String, List <String>), или как я могу сделать это лучше шаг за шагом? Спасибо!

У вашего ReadExcel чтения ReadExcel есть серьезная проблема: вместо повторного использования List , который уже отображается ключом, вы всегда создаете новый, поэтому в итоге у вас будут списки с одним единственным (последним) значением.

Вот как вы можете это исправить (используя Java 8):

 // ... while (rowIterator.hasNext()) { Row row = rowIterator.next(); Cell keyCell = row.getCell(1); Cell valCell = row.getCell(2); String key = getStringCellValue(keyCell); switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC: value = getNumericCellValue(valCell); break; case Cell.CELL_TYPE_STRING: value = getStringCellValue(valCell); break; } } // this line only compiles since Java 8 result.computeIfAbsent(key, k -> new HashSet<Object>()).add(value); } 

Если вы еще не используете Java 8, загрузите его быстро или замените последнюю строку выше:

 Set<Object> list = result.get(key); if (list == null) result.put(key, list = new HashSet<Object>()); list.add(value); 

Сравнение объектов Map довольно просто – вы можете сравнить их с помощью equals :

 if (map1.equals(map2)) { // both maps are equal! } else { // maps are NOT equal! } 

Конечно, это дает только true или false . Если вы хотите узнать подробности (какие записи отличаются), вам нужно будет сделать это самостоятельно.

  • Время загрузки с листа excel в mysql
  • Как я могу подключить ORACLE из EXCEL с помощью JDBC?
  • Драйвер Microsoft Excel Excel
  • Java JDBC-ODBC не может загрузить драйвер для Excel
  • JDBC - Где найти драйвер JDBC типа 4 для чтения файлов excel (.xml) в Linux (или даже в Windows)
  • Подключение к Excel с помощью JDBC 8
  • Oracle - лучший способ напрямую использовать данные XLSX, не используя Apache POI
  • Объединение таблиц из разных баз данных через JDBC
  • как хранить данные с листа excel в базе данных mysql, используя соединение jdbc
  • доступ к excel как базе данных с помощью jdbc
  • Как читать несколько листов Excel для хранения содержимого листа excel в базе данных
  • Interesting Posts

    VBA Ошибка времени выполнения '1004': Selection.Interior.Pattern

    расширять данные в несвязанные ячейки

    Excel Macro не работает, когда Excel открывается с помощью скрипта

    Ms Excel Заменить значение со средним значением для предыдущего и следующего значений

    Код VBA для пропуска определенных значений и замены с последующим квалификационным значением

    Чтение закладок над значениями из ячейки excel в php

    Загрузка / анализ документа Excel в приложении Rails

    Excel – используйте диапазон значений без нулей

    Использование одного или двухмерных массивов в Excel VBA

    Excel Количество номеров на разных листах

    Функция Excel назначает определенное значение определенным атрибутам, не игнорируя пустые ячейки

    Удалить ошибку защищенного листа с помощью VBA

    ExcelWorksheet.UsedRange считает неправильным, если файл имеет пустые строки сверху

    Excel VBA. Как заполнить значения ListBox из диапазона переменных?

    Как найти, где определенное число будет вписываться в строку значений в Excel?

    Давайте будем гением компьютера.