Преобразование файлов ввода в карту списка карт внутри - PullRequest
0 голосов
/ 02 мая 2019

У меня есть ввод, как показано ниже для чтения файла,

1|VegemiteScroll|VS5|3|6.99
2|VegemiteScroll|VS5|5|8.99

3|BlueberryMuffin|MB11|2|9.95
4|BlueberryMuffin|MB11|5|16.95
5|BlueberryMuffin|MB11|8|24.95

6|Croissant|CF|3|5.95
7|Croissant|CF|5|9.95



Я хотел поместить его в Hashmap, используя group by, как показано ниже. Давайте рассмотрим строки № 1, № 2.

Map obj = new HashMap();
obj.put(3,6.99);
obj.put(5,8.99);

List<Map> list = new ArrayList<>();
list.add(obj)

Map<String, List<Map>> map = new HashMap();
map.put("VS5", list);

Это для 1-го случая, а для второго и третьего случая (от # 3 до # 8),

map.put("MB11", list);  

Список содержит список карт, как указано выше. Не могли бы вы, пожалуйста, мне решить эту проблему с помощью потоков Java. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Вот решение, использующее Java 8 Streams, groupingBy и другие "модные вещи". Для простоты я предположил, что входные данные уже представлены в виде строки.

private static final int EXPECTED_LINE_ELEMENTS = 5;      
private static final int LINE_KEY_INDEX = 2;              
private static final int DATA_KEY_INDEX = 3;              
private static final int DATA_VALUE_INDEX = 4;            

private static Map<String, List<Map<Integer, Float>>> convert(final String input) {                                                                                            
    return Stream.of(input.split("\\n")) // split input by new line character                                                                                                  
        .filter(line -> !line.trim().isEmpty()) // filter out empty lines                                                                                                            
        .map(line -> line.split("\\|")) // split each line by '|' character                                                                                                          
        .filter(line -> line.length == EXPECTED_LINE_ELEMENTS) // filter out potential elements containing undesired number of columns                                   
        .collect(Collectors.groupingBy(line -> line[LINE_KEY_INDEX])) // convert to map using 3rd column as a key and a list of corresponding lines as values            
        .entrySet()                                                                                                                                                            
        .stream()                                                                                                                                                              
        .collect(                                                                                                                                                              
            Collectors.toMap(                                                                                                                                                  
                Map.Entry::getKey, // keep the same key                                                                                                                       
                stringListEntry -> Collections.singletonList(convertLinesToMap(stringListEntry.getValue())) // convert list of lines to a singleton list containing a map      
            )                                                                                                                                                                  
        );                                                                                                                                                                     
}                                                                                                                                                                              

private static Map<Integer, Float> convertLinesToMap(final List<String[]> lines) {                                                                                             
    return lines.stream()                                                                                                                                                      
        .collect(Collectors.toMap(                                                                                                                                             
            line -> Integer.valueOf(line[DATA_KEY_INDEX].trim()), // use 4th column as key of the map (mapped to Integer)                                                
            line -> Float.valueOf(line[DATA_VALUE_INDEX].trim())) // use 5th column as key of the map (mapped to Float)                                                  
        );                                                                                                                                                                     
}                                                                                                                                                                                                                                                                 

Тогда следующее:

System.out.println(convert(input));

Следует напечатать это:

{ CF =[{3=5.95, 5=9.95, 9=16.99}],  VS5 =[{3=6.99, 5=8.99}],  MB11 =[{2=9.95, 5=16.95, 8=24.95}]}

PS. Как вы написали:

Map obj = new HashMap();
obj.put(3,6.99);
obj.put(5,8.99);

Я предположил, что вы хотите, чтобы в качестве ключей были целые числа, а в качестве значений - числа с плавающей запятой. Если это не так, вы можете просто обновить соответствующие фрагменты метода convertLinesToMap.

1 голос
/ 02 мая 2019

Ниже приведен код, который служит цели.Это не оптимизировано полностью.Но это работает.

    import java.io.File;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Scanner;

    /**
     * 
     */

    /**
     * @author KishorRaskar
     *
     */
    public class Main {

        /**
         * @param args
         * @throws Exception 
         */
        public static void main(String[] args) throws Exception {
            // pass the path to the file as a parameter 
            File file = 
              new File("C:\\Data\\FAB\\WorkSpace\\Test\\MyCode\\test.txt"); 
            Scanner sc = new Scanner(file); 
            List<HashMap> mapList = new ArrayList<>();
            HashMap<String, String> dataMap = null;
            HashMap<String, List<HashMap<String, String>>> dataMapList = new HashMap<>();

            while (sc.hasNextLine()) {
                String line = sc.nextLine();
                if(null == line || line.isEmpty()) {
                    continue;
                }
                String[] dataArray = line.split("\\|");
                //System.out.println(Arrays.toString(dataArray)); 
                String dataMapKey = dataArray[3].trim();
                String dataMapValue = dataArray[4].trim();
                String dataMapListKey = dataArray[2].trim();            
                if(!dataMapList.containsKey(dataMapListKey)) {
                    dataMapList.put(dataMapListKey, new ArrayList<>());
                    dataMapList.get(dataMapListKey).add(new HashMap<>());
                }
                dataMapList.get(dataMapListKey).get(0).put(dataMapKey, dataMapValue);
              //System.out.println(line); 
            }
            System.out.println("###############################");
            System.out.println(dataMapList);
            System.out.println("###############################");
          } 
    }

Ввод: test.txt 1 |Вегемитский свиток |VS5 |3 |6,99 2 |Вегемитский свиток |VS5 |5 |8,99

3 |Черничный кекс |MB11 |2 |9,95 4 |Черничный кекс |MB11 |5 |16,95 5 |Черничный кекс |MB11 |8 |24,95

6 |Круассан |CF |3 |5,95 7 |Круассан |CF |5 |9,95 8 |Круассан |CF |9 |16.99

Выход:

############################### *

{CF = [{3 = 5,95, 5 = 9,95, 9 = 16,99}], MB11 = [{2 = 9,95, 5 = 16,95, 8 = 24,95}], VS5 = [{3= 6.99, 5 = 8.99}]} #####################################

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...