I've got a text file that I've trimmed extraneous data off of, leaving me with 4 columns. The first acts as a state identifier, and each of the next three contain some numerical information about the population of that state.

This is my first time playing with IO/file parsing and I seem to be having trouble putting together a solution to determine which lines have the same state identifier then summing together the values of columns 2, 3 and 4.

Example of what this may look like as input:

01   123   456   789
01   456   789   012

and so on

Example of what I'd like to see it become as output:

01 579 1245 801

I've tried going line by line and splitting the contents of my input file to a string array then Integer.parseInt() to turn my string contents into integers.

Have just recently tried putting together a while loop to slowly loop through my data with the intention of creating an array of the values on that line only so I can store them for performing my summations/averages.

int stateCode = 01;
while (stateCode <= 56) {                   
    if (line.startsWith(Integer.toString(stateCode))) {  
                System.out.println(stateCode);                          
            String[] stringValues = line.split("    ");                 
        for (int i = 0; + i < stringValues.length; i++) {                                
                       System.out.println(stringValues[i]);             
               }
        }   
        stateCode++;            
    }

Described what I'd like to see above! Really feel like I'm getting closer on this thing but would love to see what kinds of solutions others may consider using. Appreciate the input, all!

1 Answers

1
Andrew Tobilko On

I will give you a general idea, which may facilitate your work.

01 123 456 789

This line can be represented as an Entry<Integer, IntSummaryStatistics>, the key is a state code, the value is a statistics about that state.

Integer stateCode = Integer.valueOf(line.substring(0, line.indexOf(' ')));
IntSummaryStatistics statistics = Arrays.stream(line.substring(line.indexOf(' ')).split(" "))
                                        .filter(s -> !s.isEmpty())
                                        .mapToInt(Integer::valueOf)
                                        .summaryStatistics();

Having these two values, you can form a recond and put it into a Map.

map.put(stateCode, statistics);

You proceed with next elements, and check if the statistics for the state being processed has already been calculated. If so, you calculate a new one, and merge the two.

map.compute(stateCode, (key, oldValue) -> {
    if (oldValue == null) {
        return statistics;
    }
    oldValue.combine(statistics);
    return oldValue;
});