Adding key value pairs from a file to a Hashmap

TheKraven :

I am trying to extract a key value pair from a file to a Hashmap for easier manipulation of values.

The file is in this format:

Activity1:3:Activity2:5:Activity3:7:
Activity4:1: 

Each line has a maximum of 3 activities and its corresponding number.

String currentPath;
Path fullPath;
HashMap<String, String> hm = new HashMap<>();

try {
    // Obtain current directory path
    currentPath = Paths.get("").toAbsolutePath().toString();
    // Obtain full path of data.txt
    fullPath = Paths.get(currentPath, "data.txt");
    // Check if file exists
    if (Files.exists(fullPath)) {
        // Read line by line in data.txt
        Files.lines(fullPath)
                .forEach(line -> hm.put(line.split(":")[0], line.split(":")[1]) );
    }
    else{
        System.out.println("data.txt is not found.");
    }
} catch (
        IOException e) {
    e.printStackTrace();
}

However, only the first key:value pair is inserted into the Hashmap. I tried to use

.map(s -> s.split(":"))
.collect(Collectors.toMap(r -> r[0], r -> r[1] ))

but it does not work as the split() output type is an Array which toMap doesn't accept.

Edit:

public static void main(String[] args) {

        String currentPath;
        Path filePath;
        HashMap<String, String> hm = new HashMap<>();
        Pattern delimiter = Pattern.compile(":");

        try {
            // Obtain current directory path
            currentPath = Paths.get("").toAbsolutePath().toString();
            // Obtain full path of data.txt
            filePath = Paths.get(currentPath, "data.txt");
            // Check if file exists
            if (Files.exists(filePath)) {
                // Read line by line in data.txt
                    hm = Files.lines(filePath)
                        .map(delimiter::split) // stream of multiple Array<String>
                        .flatMapToInt(a -> IntStream.range(0, a.length - 1))  // combine multiple Array<String> to a
                            // single stream, remove last Array<String>
                        .filter(i -> i % 2 == 0)  // obtain only even indices
                        .mapToObj(i -> new AbstractMap.SimpleEntry<>(a[i], a[i+1])) // a cannot be resolved. Create new Map, key is Array<String>[even], value is Array<String>[odd]
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a,b) -> a)); //
            }
            else{
                System.out.println("data.txt not found.");
            }
        } catch (
                IOException e) {
            e.printStackTrace();
        }

        for (String objectName : hm.keySet()) {
            System.out.println(objectName);
            System.out.println(hm.get(objectName));
        }
    }
Ravindra Ranwala :

First let's take a look at why your solution does not give intended result. When you split each line around the delimiter : then there may be many key value pairs. But you just consider the first key value pair while omitting the rest. So this works for the last line in your example since it has only one corresponding map entry. At the same time it does not work for the first line since it has many corresponding map entries while you are treating only the first entry.

And here's my approach for solving this problem. Take each line in your file and split it around the delimiter :. This yields an array to each corresponding line. Since every line has a trailing : character, you have to skip the relevant last element in the array. Then each even indice in the array becomes the key in the map, and the immediately following odd index becomes the corresponding value. Here's how it looks.

private static final Pattern DELIMITER = Pattern.compile(":");
Map<String, String> activityMap = lines.map(DELIMITER::split)
    .flatMap(a -> IntStream.range(0, a.length - 1).filter(i -> i % 2 == 0)
        .mapToObj(i -> new AbstractMap.SimpleEntry<>(a[i], a[i + 1])))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a));

And the output looks like this:

{Activity3=7, Activity4=1, Activity1=3, Activity2=5}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=139702&siteId=1