-1

I am working on an assignment where I have 2 URLs. The first has 3 columns, the first column is the lower bin boundary, the second is the upper bin boundary and the third is irrelevant for this question but just contains another number. it looks something like this.

100 101 3.45
101 102 4.23
103 104 2.40
.. ... ....
199 200 6.89

the second URL contains 1 of 2 possible id codes in the first column and a number in the second, lets call them heights. it looks something like this

xx 108.45
xx 122.00
yy 124.78
xx 156.93

In previous parts I have already read and stored the data into array list, and processed some of the data from the first URL.

Now I need to find for both id codes separately the frequencies of the heights for each of the given bins. I've looked around and tried a few things but I have not really got kind of near to want I need. I am still unsure whether the best way to do this is with a hash map, array list or another type of collection? Any help?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • I tried to answer this but had some problems myself, so I asked my own question. https://stackoverflow.com/questions/27370398/how-to-target-entries-in-a-map-of-lists . You may know how to solve my problem, and in the process solve yours... :) – localhost Dec 09 '14 at 02:17

1 Answers1

0

I had a go at this for a bit of practice on collections. Thanks to @Eran for the help in my other question, I was able to work it out.

I added a bit extra to the input for testing, since the values that you gave didn't actually go in any of the bins!

package soBins;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Bins {

    public static void main(String[] args) {

        String rangeIn = "100 101 3.45\n101 102 4.23\n103 104 2.40\n199 200 6.89";

        String dataIn = "xx 108.45\nxx 122.00\nyy 124.78\nxx 156.93\nzz 101.5\nxx 103.5\nzz 101.25";

        Scanner rangeScanner = new Scanner(rangeIn);
        Scanner dataScanner = new Scanner(dataIn);  

        ArrayList<Bin> bins = new ArrayList<Bin>();
        while (rangeScanner.hasNextLine()) {
            String line = rangeScanner.nextLine();
            String[] tokens = line.split(" ");
            int min = Integer.parseInt(tokens[0]);
            int max = Integer.parseInt(tokens[1]);
//          System.out.println("Creating new bin, min "+ min + ", max "+ max);
            bins.add(new Bin(min,max));
        }
        rangeScanner.close();

        Map<String,ArrayList<Bin>> namedBins = new HashMap<String,ArrayList<Bin>>();
        while (dataScanner.hasNextLine()) {
            String line = dataScanner.nextLine();
            String[] tokens = line.split(" ");
            String name = tokens[0]; // name is first token on line
            float data = Float.parseFloat(tokens[1]); // data is second token on line

            if (!namedBins.containsKey(name)) {
                ArrayList<Bin> newBins = new ArrayList<Bin>();

                for (Bin bin : bins) {
                    newBins.add (new Bin(bin)); // using a copy constructor            
                }
                namedBins.put(name,newBins);
            }
            for (Bin b : namedBins.get(name)) {
                if (b.isInRange(data)) {
                    System.out.println("adding "+ data + " to bin in "+ name);
                    b.addData(data);
                }
            }
        }
        dataScanner.close();

        System.out.println("All bins and data contents:");
        for (String dataName : namedBins.keySet()) { // print all values and bin ranges
            for (Bin range : namedBins.get(dataName)) {
                System.out.println(dataName + ", min " + range.getMin() + ", max " + range.getMax()
                        + ", data is " + range.getData());              
            }
        }
    }
}

And my Bin class:

package soBins;

import java.util.ArrayList;

public class Bin {

    int min = 0;
    int max = 0;
    ArrayList<Float> values = new ArrayList<Float>();

    Bin(int min,int max) {
        this.min = min;
        this.max = max;
    }

    public Bin(Bin bin) {
        this.min = bin.min;
        this.max = bin.max;
        for (float f : bin.values) {
            this.values.add(f);
        }
//      this.values.addAll(bin.values);  // also worked
//      this.values = (ArrayList<Float>) bin.values.clone(); // also worked but gave unchecked cast warning
    }

    public boolean isInRange(float data) {
        return (min < data) && (data < max);
    }

    public void addData(float data) {
        values.add(data);
    }

    public int getMin() {
        return min;
    }
    public void setMin(int min) {
        this.min = min;
    }
    public int getMax() {
        return max;
    }
    public void setMax(int max) {
        this.max = max;
    }

    public ArrayList<Float> getData() {
        return values;
    }   

}

Output:

adding 101.5 to bin in zz
adding 103.5 to bin in xx
adding 101.25 to bin in zz
All bins and data contents:
zz, min 100, max 101, data is []
zz, min 101, max 102, data is [101.5, 101.25]
zz, min 103, max 104, data is []
zz, min 199, max 200, data is []
yy, min 100, max 101, data is []
yy, min 101, max 102, data is []
yy, min 103, max 104, data is []
yy, min 199, max 200, data is []
xx, min 100, max 101, data is []
xx, min 101, max 102, data is []
xx, min 103, max 104, data is [103.5]
xx, min 199, max 200, data is []
localhost
  • 1,253
  • 4
  • 18
  • 29