0

i'm trying to find a way to take 2 txt files, read them into my java class (put them in hash map) and then connect them into one hash map (which i will write latter into a txt file) something like this: i want txt3 to have all the words from txt1 and txt2

txt1

word1 -> [a] [b] [c]
word2 -> [r]

txt2

word1 -> [z] [d] 
word3 -> [k]

txt3 - what i want to create

word1 -> [a] [b] [c] [z] [d]
word2 -> [r]
word3 -> [k]

in my code

wordline[0] = word1

wordline[1] = ->

wordline[2] = [a][b][c]

code

public void readPartialPosting() {
    HashMap<String, String>[] dictionary1 = new HashMap[2];
    dictionary1[0]=new HashMap<>();
    dictionary1[1]=new HashMap<>();
    File fromFile;
    BufferedReader br = null;
    try {
        fromFile = new File("1.txt");
        br = new BufferedReader(new FileReader(fromFile));
        String st;
        String[] wordLine;
        String term;
        String termLocation;
        while ((st = br.readLine()) != null) {
            wordLine = st.split(" ", 3);
            term = wordLine[0];
            termLocation = wordLine[2];
            dictionary1[0].put(term, termLocation);
        }
        fromFile = new File("2.txt");
        br = new BufferedReader(new FileReader(fromFile));
        while ((st = br.readLine()) != null) {
            wordLine = st.split(" ", 3);
            term = wordLine[0];
            termLocation = wordLine[2];
            dictionary1[1].put(term, termLocation);
        }
    } catch (Exception e) {
    }

}

so at the end of code basically i have the txt1 and txt2 from above and now im trying to create txt3 somehow, but i'm not sure how to connect the list in case i have duplicate key (and then i just want to add the strings together one after each other and not overwrite)

i'm not even sure if my idea for hash map is the right solution here maybe a different structure?

i saw compute function while reading on the forum but i'm not sure if that can help me and not sure how to use exactly.

hope i post in forum like asked in tips. thanks for the help!

Itzik Dan
  • 15
  • 3

2 Answers2

2

Using Java 8 features the two Map objects in dictionary1 can be combined as follows.

Note: Changed dictionary1 from array to List to eliminate compiler warnings/errors about generic arrays. You shouldn't use generic arrays if you can avoid it.

Solution (Java 8+)

Map<String, String> merged = new TreeMap<>();
dictionary1.forEach(d -> 
    d.forEach((k, v) ->
        merged.merge(k, v, (v1, v2) -> v1 + " " + v2)
    )
);

Changed HashMap to TreeMap so result is in alphabetical order.

Test (Java 9+)

List<Map<String, String>> dictionary1 = List.of(
        Map.of("word1", "[a] [b] [c]",
               "word2", "[r]"),
        Map.of("word1", "[z] [d]",
               "word3", "[k]")
);
// code from above here
merged.entrySet().forEach(System.out::println);

Output

word1=[a] [b] [c] [z] [d]
word2=[r]
word3=[k]
Andreas
  • 138,167
  • 8
  • 112
  • 195
  • you can simplify it further as Maps have a `forEach` i.e. `dictionary1.forEach(d -> d.forEach((key, value) -> merged.merge(key, value, (v1, v2) -> v1 + " " + v2)));` – Ousmane D. Dec 01 '18 at 01:04
  • @Aomine Thanks. Forgot about that one. Answer updated. :-) – Andreas Dec 01 '18 at 01:20
  • thanks for answer, i have a problem tho i'm new to lambda expression. first i get an error at "List.of( Map.of("word1", "[a] [b] [c]", "word2", "[r]"), Map.of("word1", "[z] [d]", "word3", "[k]")" with the words "of" it says "cannot resolve method of" btw, im using jdk 8 beacuse of javafx support that is lost in future sdk's------------- second question "You shouldn't use generic arrays if you can avoid it." what is the problem with generic arrays? since my code does work if i do " List> dictionary1 = new ArrayList>(); " – – Itzik Dan Dec 01 '18 at 09:42
  • @ItzikDan #1 The test code is Java 9, but the solution is Java 8. --- #2 See [What's the reason I can't create generic array types in Java?](https://stackoverflow.com/q/2927391/5221149) – Andreas Dec 03 '18 at 16:42
0

First of all, I would recommend you to encapsulate creating dictionary from the file into separate method:

public static Map<String, String> createFileDictionary(String path) throws IOException {
    File fromFile = new File(path);

    try (BufferedReader br = new BufferedReader(new FileReader(fromFile))) {
        Map<String, String> dictionary = new HashMap<>();
        String str;

        while ((str = br.readLine()) != null) {
            String[] parts = str.split(" ", 3);
            dictionary.put(parts[0], parts[2]);
        }

        return dictionary;
    }
}

Then using you can ready your files and put all dictionaries' items into single map.

// java 8 or higher
private static void putAll(Map<String, String> dest, Map<String, String> src) {
    src.forEach((key, val) -> dest.merge(key, val, (s1, s2) -> s1 + ' ' + s2));
}

// java 7 or earlier
private static void putAll(Map<String, String> dest, Map<String, String> src) {
    for (Map.Entry<String, String> entry : src.entrySet()) {
        if (dest.containsKey(entry.getKey()))
            dest.put(entry.getKey(), dest.get(entry.getKey()) + ' ' + entry.getValue());
        else
            dest.put(entry.getKey(), entry.getValue());
    }
}

And use it in your client's code:

Map<String, String> fileDictionary = new HashMap<>();
putAll(fileDictionary, createFileDictionary("1.txt"));
putAll(fileDictionary, createFileDictionary("2.txt"));
oleg.cherednik
  • 12,764
  • 2
  • 17
  • 25