I am struggling to get my code in Java to do the following:
Inventory Update program.
The first set of records is the master file which reflects an item inventory at the start of the business day. Each master file record contains a part number and a corresponding item stock quantity. Let us assume that the master file contains no more than 5 records.
The second set of records reflects the transactions for each of various items during that day. Transaction records contain have the same format as the master file records: they contain the item number and the corresponding total number of items sold that day. There is unknown number of such transaction records in the input file.
Write a program to update the master file against the transaction file to produce the new master file at the end of the day. A record notice should accompany any item number for which fewer than 10 items remain in the stock.
The actual files look like this. (Master.txt)
444 40
111 30
222 15
134 20
353 5
And the second looks like this (Sales.txt)
134 03
111 29
353 02
222 10
And the updated version of Master.txt should look like this.
444 40
111 1 reorder
222 5 reorder
134 17
353 3 reorder
Here is my code.
import java.io.*;
import java.util.*;
public class inventoryUpdate {
//Exception included due to mOrganize, sOrganize, and PrintWriter
public static void main(String[] args) throws Exception {
Scanner inKey = new Scanner(System.in);
//Preparing the document based on how many item types were sold.
System.out.println("How many types of products were sold?");
int sold = inKey.nextInt();
int[][] inMaster = fileCheck(mOrganize(), sOrganize(sold), sold);
PrintWriter printFile = new PrintWriter("Master.txt");
printFile.println("Item No. \tQuantity");
for (int i = 0; i<5;i++){
if (inMaster[i][1] < 10){
printFile.printf("%-5s %17s You are low in inventory on this item. Please order more.\n", inMaster[i][0], inMaster[i][1]);
}
else{
printFile.printf("%-5s %17s\n", inMaster[i][0], inMaster[i][1]);
}
}
printFile.close();
System.out.println(Arrays.deepToString(inMaster));
}
private static int[][] mOrganize() throws Exception {
File fileRip = new File("Master.txt");
Scanner masterRead = new Scanner(fileRip);
masterRead.nextLine();
int[][] masterData = new int [5][2];
for (int i = 0; i < 5; i++){
for (int i2 = 0; i2 < 2; i2++){
masterData[i][i2] = masterRead.nextInt();
if (masterData[i][i2] < 10){
masterRead.nextLine();
}
}
}
masterRead.close();
return masterData;
}
private static int[][] sOrganize(int sold) throws Exception{
File fileRip = new File ("Sales.txt");
Scanner saleRead = new Scanner(fileRip);
saleRead.nextLine();
int [][] salesData = new int [sold][2];
for (int i = 0; i < sold; i++){
for (int i2 = 0; i2 < 2; i2++){
salesData[i][i2] = saleRead.nextInt();
}
}
saleRead.close();
return salesData;
}
private static int[][] fileCheck(int[][] master, int[][] sales, int sold){
int columnBase = 0;
for(int i = 0; i < 5; i++){
for(int i2 = 0; i2 < sold; i2++){
if (master[i][columnBase] == sales[i2][columnBase]){
master[i][columnBase + 1] -= sales[i2][columnBase + 1];
}
}
}
return master;
}
}
My output is as follows.
How many types of products were sold?
4
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at inventoryUpdate.mOrganize(inventoryUpdate.java:39)
at inventoryUpdate.main(inventoryUpdate.java:14)
The code appears to break at line 14 and is related to my inMaster array.
int[][] inMaster = fileCheck(mOrganize(), sOrganize(sold), sold);
I am sure I am overlooking a syntax error of sorts, but I am failing to wrap my brain around it.
I would appreciate any help possible.
Your problem is probably a lack of making your methods too specific, and you expect too much precision in the input.
In mOrganize, you are explicitly reading away the new lines. However, the last line doesn't contain any newline, so it fails.
To be perfectly honest, nextInt happily skips whitespace, so none of the nextLine statements are necessary at all and your code runs if you remove them.
mOrganize should just be called organize if you follow Java naming conventions, and just readInventory with a File parameter if you want to let it make any sense.
I'm not sure how much you've learned about programming, but things like 5 and 10 in mOrganize are called magic values and should be avoided. What you really want is to create a class e.g. ItemInventory and ItemSales, make a Java List out of those and then read the files until the end. That way your code will work even if there are more or fewer lines in the files.
Here is a bit more advanced example that uses a Map rather than a List:
private static Map<Integer, Integer> readInventory(File file) throws IOException {
var inventory = new HashMap<Integer, Integer>();
try (var lineScanner = new Scanner(file)) {
while (lineScanner.hasNextLine()) {
// we assume each item is on it's own line
var line = lineScanner.nextLine();
try (var itemScanner = new Scanner(line)) {
var no = itemScanner.nextInt();
var amount = itemScanner.nextInt();
if (inventory.put(no, amount) != null) {
// a more specific exception such as InventoryException might be better
throw new RuntimeException("Duplicate item in inventory file");
}
}
}
}
return inventory;
}
an item number is unique after all, and you would not expect it twice in the same inventory.
As you can see, it would be easy to put more information in the same line now, although that would mean changing the return value to something other than Map<Integer, Integer> - for instance Map<Item, Integer> if you define a new Item class.
It is now completely independent of the amount of items in the file, no magic numbers anymore. It also is able to read from any file, rather than just Master.txt.
I hope it is abundantly obvious that rewriting "Master.txt" won't help you with debugging, as you need to restore it each time you run the code.
Related
I'm trying to work out the most expensive county to rent a building from data in a CSV file. The data from each column I need the data from has been put into a list. The price range is set by the user so the outer most for loop and if statement ensure that the buildings considered are in the set price range.
The price of a building is also slightly complicated because the price is the minimum stay x price.
In the code below I am trying to get the average property value of one county just son I can get the basic structure right before I carry on, but I'm kind of lost at this point any help would be much appreciated.
public int sampleMethod()
{
ArrayList<String> county = new ArrayList<String>();
ArrayList<Integer> costOfBuildings = new ArrayList<Integer>();
ArrayList<Integer> minimumStay = new ArrayList<Integer>();
ArrayList<Integer> minimumBuildingCost = new ArrayList<Integer>();
try{
//Code to read data from the CSV and put the data in the lists.
}
}
catch(IOException | URISyntaxException e){
//Some code.
}
int count = 0;
int avgCountyPrice = 0;
int countyCount = 0;
for (int cost : costOfBuildings) {
if (costOfBuildings.get(count) >= controller.getMin() && costOfBuildings.get(count) <= controller.getMax()) {
for (String currentCounty: county) {
for (int currentMinimumStay: minimumStay) {
if (currentCounty.equals("sample county")) {
countyCount++;
int temp = nightsPermitted * cost;
avgCountyPrice = avgCountyPrice + temp / countyCount;
}
}
}
}
count++;
}
return avgCountyPrice ;
}
Here is a sample table to depict what the CSV looks like, also the CSV file has more than 50,000 rows.
name
county
price
minStay
Morgan
lydney
135
5
John
sedury
34
1
Patrick
newport
9901
7
Let’s describe the algorithm of your task: Group the CSV file by county, calculate the average price in each group, and find the country that has the highest average price for buildings. The code will be rather long if you try to finish the task using Java. It is convenient and simple to get this done in SPL, the open-source Java package. The language only needs one line of code:
A
1
=file("data.csv").import#ct().groups(county;avg(price):price_avg).top(-1;price_avg).county
SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as mostExpensiveCounty.splx and invoke it in Java in the same way you call a stored procedure:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call mostExpensiveCounty()");
st.execute();
…
I'm currently building a gamebook text based adventure program which will accept a certain format of txt file which looks like the one below.
Now this may all seem pretty simple however, I need to create Section objects in order for my game to work properly. As you can see above, the sections are often different sizes depending on how many possible choices they have to their appropriate story text. My section object has the declaration of
Section(String storytext, String choiceText, int choiceSections)
And I need to pull the appropriate details from this text file. I was reading through some forums and found an somewhat appropriate looking approach to the reading through the text file. The code was as follows which works in triplets, not necessarily good for me as my text files come in variable lengths. And obviously this is just an example of code, I would need to parse out both integers and strings.
Car[] car = new Car[length/3];
for (int i = 0; i < length/3; i ++) //
{
int startReading = Integer.parseInt(inputFile.readLine());
int endReading = Integer.parseInt(inputFile.readLine());
int liter = Integer.parseInt(inputFile.readLine());
car[i] = new Car (startKm, endKm, litre);
}
This seems like it would work for me however, I need my loop to update dynamically based upon a few criteria. #1 > The number on the first line which is the total number of section objects which will be created. #2 > The number on the total choices line which will determine how many more lines the line reader needs to run through before stopping and creating the object. I'm quite lost on how to create a proper loop which will create my objects based on this criteria for these text files.
6 < Number of "sections" in the game
1 < Section number (1)
While making a peanut butter and jam sandwich one evening you discover that you’ve run out of strawberry jam. < Story text associated with the section
2 < Number of possible choices
5 < The choice below leads to this section
If you make do with grape jelly, click here. < This is one of the choices
4 < The choice below leads to this section
If you head out to the store to buy strawberry jam, click here. < This is one of the choices
2 < Section number (2)
You arrive home and begin making a fresh sandwich with your favourite condiment. You lovingly spread the peanut butter and the strawberry jam, salivating at the wonderful aroma. Unable to resist any longer, you take a bite. Utter bliss envelopes you, the perfect blend of flavours a cascade of awesomeness filling your consciousness. < Story text associated with this section
0 < Number of possible choices
3 < Section Number (3)
Your stomach immediately starts to hurt. Pain stabs at your abdomen and you double over, gasping for breath. The floor crashes up and darkness clouds your vision. < Story text associated with this section
0 < Number of possible choices
4 < Section Number (4)
You rush to the grocery store and look for your favourite brand of strawberry jam. You are surprised to find a new variety, fieldberry, on the shelf beside the familiar jar. < Story text associated with this section
2 < Number of possible choices
2 < The choice below leads to this section
If you buy the strawberry jam, click here. < This is one of the choices
6 < The choice below leads to this section
If you buy the new fieldberry jam, click here. < This is one of the choices
5 < Section Number (5)
You dig around in the fridge for a while and find the grape jelly you remembered was back there. It smells a bit funky, but you slather it onto your bread just the same, holding your breath a bit. < Story text associated with this section
2 < Number of possible choices
3 < The choice below leads to this section
If you eat the smelly sandwich, click here. < This is one of the choices
4 < The choice below leads to this section
If you toss it in the garbage and go out to buy jam, click here. < This is one of the choices
6 < Section Number (6)
You arrive home and begin making a fresh sandwich with your exciting new
condiment. You lovingly spread the peanut butter and the fieldberry jam, salivating at the wonderful aroma. Unable to resist any longer, you take a bite. < Story text associated with this section
1 < Number of possible choices
//do not know the choice here yet.
3 < Choice section you are led too, 3 represents winning so it finishes at this point.
This will do:
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(
"C:\\path\\to\\file"))) {
String line = br.readLine().trim(); // may throw IOException
int num_of_sections = Integer.parseInt(line);
List<Section> sections = new ArrayList<>(num_of_sections);
for (int j = 1; j <= num_of_sections; ++j) {
line = _skip_empty(br);
int section_number = Integer.parseInt(line);
String section_text = _skip_empty(br);
line = _skip_empty(br);
int num_choices = Integer.parseInt(line);
List<Choice> choices = new ArrayList<>(num_choices);
for (int choice = 0; choice < num_choices; ++choice) {
line = _skip_empty(br);
int go_to_section = Integer.parseInt(line);
String choice_text = _skip_empty(br);
choices.add(new Choice(go_to_section, choice_text));
}
sections.add(new Section(section_number, section_text, choices));
}
}
}
private static class Section {
private final int sectionNumber;
private final String storyText;
private final List<Choice> choices;
Section(int sectionNumber, String storyText, List<Choice> choices) {
this.sectionNumber = sectionNumber;
this.storyText = storyText;
this.choices = choices;
}
public String getStoryText() {
return storyText;
}
public List<Choice> getChoices() {
return choices;
}
public int getSectionNumber() {
return sectionNumber;
}
}
private static class Choice {
private final int leadsToSection;
private final String choiceText;
Choice(int leadsToSection, String choiceText) {
this.leadsToSection = leadsToSection;
this.choiceText = choiceText;
}
public int getLeadsToSection() {
return leadsToSection;
}
public String getChoiceText() {
return choiceText;
}
}
private static String _skip_empty(BufferedReader br) throws IOException {
String line;
do {
line = br.readLine();
if (line == null) return ""; // winning choice does that
line = line.trim();
} while (line.isEmpty());
return line;
}
}
As you see I changed your Section class to accept a list of choices - that's more appropriate
I am writing a program that will import values from a txt file in to an array, I then need to count how many of those elements are greater than or equal to 36. The data imports fine, and the total amount of values it displays is correct, but I can not get it display the amount of times the number 36 is found in the file. Thanks for any help!
public static void main(String[] args) throws Exception {
int[] enrollments = new int [100];
int count;
int FullClass;
double ClassPercentage;
return count (number of data items)
count = CreateArray(enrollments);
System.out.println (count );
FullClass = AddValues (enrollments);
System.out.println (FullClass)
ClassPercentage= FullClass/count;
System.out.print(ClassPercentage +"% of classes are full");
}//end main
/**
*
* #param classSizes
*/
public static int CreateArray(int[] classSizes) throws Exception{
int count = 0;
File enrollments = new File("enrollments.txt");
Scanner infile = new Scanner (enrollments);
while (infile.hasNextInt()){
classSizes[count] = infile.nextInt();
count++}//end while
return count; //number of items in an array
} // end CreateArray
/**************************************************************************/
/**
*
* #throws java.lang.Exception
*/
public static int AddValues (int[] enrollments) throws Exception{
{
int number = 0;
int countOf36s = 0;
while (infile.hasNextInt()) {
number = infile.next();
classSizes[count] = number;
if(number>=36) {
countOf36s++;
}
count++;
}
return countOf36s;
}// end AddValues
}//end main
Try this code to count the numbers that are greater than or equal to 36 while you are reading the file only. Change the code in your createArray method or write the below logic where ever you want to.
I tried executing this program. It works as expected. See below code
import java.util.*;
import java.io.*;
public class Test { //Name this to your actual class name
public static void main(String[] args) throws Exception {
int[] enrollments = new int [100]; //assuming not more than 100 numbers in the text file
int count; //count of all the numbers in text file
int FullClass; //count of numbers whose value is >=36
double ClassPercentage;
count = CreateArray(enrollments);
System.out.println (count);
FullClass = AddValues (enrollments);
System.out.println (FullClass);
ClassPercentage= FullClass/count;
System.out.print(ClassPercentage +"% of classes are full");
}
//Method to read all the numbers from the text file and store them in the array
public static int CreateArray(int[] classSizes) throws Exception {
int count = 0;
File enrollments = new File("enrollments.txt"); //path should be correct or else you get an exception.
Scanner infile = new Scanner (enrollments);
while (infile.hasNextInt()) {
classSizes[count] = infile.nextInt();
count++;
}
return count; //number of items in an array
}
//Method to read numbers from the array and store the count of numbers >=36
public static int AddValues (int[] enrollments) throws Exception{
int number = 0;
int countOf36s = 0;
for(int i=0; i<enrollments.length; i++) {
number = enrollments[i];
if(number>=36) {
countOf36s++;
}
}
return countOf36s;
}
}
Your code indicates that you might have misunderstood a couple of concepts and stylistic things. As you say in your comments you are new at this and would like some guidance as well as the answer to the question - here it is:
Style
Method names and variable names are by convention written starting with a lower case letter and then in camel case. This is in contrast to classes that are named starting with an upper case letter and camel case. Sticking to these conventions make code easier to read and maintain. A full list of conventions is published - this comment particularly refers to naming conventions.
Similarly, by convention, closing braces are put on a separate line when they close loops or if-else blocks.
throws Exception is very general - it's usual to limit as much as possible what Exceptions your code actually throws - in your case throws FileNotFoundException should be sufficient as this is what Scanner or File can throw at runtime. This specificity can be useful to any code that uses any of your code in the future.
Substance
You are creating the array up front with 100 members. You then call CreateArray which reads from a file while that file has more integers in it. Your code does not know how many that is - let's call it N. If N <= 100 (there are 100 integers or less), that's fine and your array will be populated from 0 to N-1. This approach is prone to confusion, though - the length of your array will be 100 no matter how many values it has read from the file - so you have to keep track of the count returned by CreateArray.
If N > 100 you have trouble - the file reading code will keep going, trying to add numbers to the array beyond its maximum index and you will get a runtime error (index out of bounds)
A better approach might be to have CreateArray return an ArrayList, which can have dynamic length and you can check how many there are using ArrayList.size()
Your original version of AddValues called CreateArray a second time, even though you pass in the array which already contains the values read from file. This is inefficient as it does all the file I/O again. Not a problem with this small example, but you should avoid duplication in general.
The main problem. As per prudhvi you are checking the number of integers in the file against 36, not each value. You can rectify this as suggested in that answer.
You do ClassPercentage= FullClass/count; Although ClassPercentage is a double, somewhat counter intuitively - because both the variables on the Right Hand Side (RHS) are int, you will have an int returned from the division which will always round down to zero. To make this work properly - you have to change (cast) one of the variables on the RHS to double before division e.g. ClassPercentage= ((double)FullClass)/count;.
If you do keep using arrays rather than ArrayList, be careful what happens when you pass them into methods. You are passing by reference, which means that if you change an element of an array in your method, it remains changed when you return from that method.
In your new version you do
...
classSizes[count] = number;
if(number>=36) {
...
You almost certainly mean
...
number = classSizes[count];
if(number>=36) {
...
which is to say in programing the order of the assignment equals is important, so a = b is not equivalent to b = a
Code
A cleaned up version of your code - observing all the above (I hope):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class ClassCounter
{
public static void main(String[] args) throws FileNotFoundException
{
int count;
int fullClass;
double classPercentage;
ArrayList<Integer> enrollments = createArray();
count = enrollments.size();
System.out.println(count);
fullClass = addValues(enrollments);
System.out.println(fullClass);
classPercentage = fullClass / count;
System.out.print(classPercentage + "% of classes are full");
}
/**
* scans file "enrollments.txt", which must contain a list of integers, and
* returns an ArrayList populated with those integers.
*
* #throws FileNotFoundException
*/
public static ArrayList<Integer> createArray() throws FileNotFoundException
{
ArrayList<Integer> listToReturn = new ArrayList<Integer>();
File enrollments = new File("enrollments.txt");
Scanner infile = new Scanner(enrollments);
while (infile.hasNextInt())
{
listToReturn.add(infile.nextInt());
}
return listToReturn;
}
/**
* returns the number of cases where enrollments >= 36 from the list of
* all enrollments
*
* #param enrollments - the list of enrollments in each class
* #throws FileNotFoundException
*/
public static int addValues(ArrayList<Integer> enrollments)
{
int number = 0;
int countOf36s = 0;
int i = 0;
while (i < enrollments.size())
{
number = enrollments.get(i);
if (number >= 36)
{
countOf36s++;
}
}
return countOf36s;
}
}
Im currently working on a program and any time i call Products[1] there is no null pointer error however, when i call Products[0] or Products[2] i get a null pointer error. However i am still getting 2 different outputs almost like there is a [0] and 1 or 1 and 2 in the array. Here is my code
FileReader file = new FileReader(location);
BufferedReader reader = new BufferedReader(file);
int numberOfLines = readLines();
String [] data = new String[numberOfLines];
Products = new Product[numberOfLines];
calc = new Calculator();
int prod_count = 0;
for(int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if(data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
System.out.println(Products[prod_count].getName());
BigDecimal price = new BigDecimal(data[2]);
Products[prod_count].setPrice(price);
for(String dataSt : data)
{
if(dataSt.toLowerCase().contains("imported"))
{
Products[prod_count].setImported(true);
}
else{
Products[prod_count].setImported(false);
}
}
calc.calculateTax(Products[prod_count]);
calc.calculateItemTotal(Products[prod_count]);
prod_count++;
This is the output :
imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62
This print works System.out.println(Products[1].getProductTotal());
This becomes a null pointer System.out.println(Products[2].getProductTotal());
This also becomes a null pointer System.out.println(Products[0].getProductTotal());
You're skipping lines containing "input".
if(data[i].contains("input")) {
continue; // Products[i] will be null
}
Probably it would be better to make products an ArrayList, and add only the meaningful rows to it.
products should also start with lowercase to follow Java conventions. Types start with uppercase, parameters & variables start with lowercase. Not all Java coding conventions are perfect -- but this one's very useful.
The code is otherwise structured fine, but arrays are not a very flexible type to build from program logic (since the length has to be pre-determined, skipping requires you to keep track of the index, and it can't track the size as you build it).
Generally you should build List (ArrayList). Map (HashMap, LinkedHashMap, TreeMap) and Set (HashSet) can be useful too.
Second bug: as Bohemian says: in data[] you've confused the concepts of a list of all lines, and data[] being the tokens parsed/ split from a single line.
"data" is generally a meaningless term. Use meaningful terms/names & your programs are far less likely to have bugs in them.
You should probably just use tokens for the line tokens, not declare it outside/ before it is needed, and not try to index it by line -- because, quite simply, there should be absolutely no need to.
for(int i = 0; i < numberOfLines; i++) {
// we shouldn't need data[] for all lines, and we weren't using it as such.
String line = reader.readLine();
String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
//
if (tokens[0].equals("input")) { // unclear which you actually mean.
/* if (line.contains("input")) { */
continue;
}
When you offer sample input for a question, edit it into the body of the question so it's readable. Putting it in the comments, where it can't be read properly, is just wasting the time of people who are trying to help you.
Bug alert: You are overwriting data:
String [] data = new String[numberOfLines];
then in the loop:
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
So who knows how large it is - depends on the success of the split - but your code relies on it being numberOfLines long.
You need to use different indexes for the line number and the new product objects. If you have 20 lines but 5 of them are "input" then you only have 15 new product objects.
For example:
int prod_count = 0;
for (int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if (data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
// etc.
prod_count++; // last thing to do
}
I'm new to Stack Overflow, and this is my first question/post! I'm working on a project for school using Java. The first part I'm having trouble with inolves:
Read each line in a file (listed at the end of my post) one time
Create a "ragged" array of integers, 4 by X, where my 4 rows will be the "region number" (the number found in the Nbr of Region) column, and fill each column with the state population for that region.
So, for example, Row 1 would hold the state populations of Region 1 resulting in 6 columns, Row 2 represents Region 2 resulting in 7 columns, and so on resulting in a "ragged" array.
My question is how to populate, or what would be the best way to populate my array with the results of my file read? I know how to declare the array, initialize the array and create space in the array, but I'm not sure of how to write my method in my State class to populate the results of my file read into the array. Right now I'm getting an "out of bounds" error when I try to compile this code using Netbeans.
Here is my code for Main and State. my input file is listed beneath it:
import java.util.*;
import java.io.*;
public class Main
{
public static void main(String[] args) throws IOException
{
// create new jagged array obj and fill it with some
// initial "dummy" values
int[][] arrPopulation =
{
{0,1,2,3,4,5},
{0,1,2,3,4,5,6},
{0,1,2,3,4,5,6,7,8,9},
{0,1,2,3,4,5,6,7,8,9,10}
};//end array declaration
// read in file States.txt, instantiate BufferedReader object,
// set new BufferedReader object to variable #newLine
FileReader f = new FileReader("States.txt");
BufferedReader br = new BufferedReader(f);
String newLine = br.readLine();
for (int rows = 0; rows < arrPopulation.length; rows++)
{
for (int col = 0; col < arrPopulation[col].length; col++) {
System.out.print(arrPopulation[rows][col] + " ");
}
// display on new lines; print out in a "table" format
System.out.println();
} // end for
State newState = new State(newLine);
int count = 0;
while(newLine != null)
{
newLine = br.readLine();
System.out.println(newState.getRegionNum());
}// end while
br.close();//close stream
} // end public static void main
} // end main
This is what I have for my State class so far:
import java.util.*;
public class State
{
private String statePop, stateNum, regionNum;
public State(String fileRead)
{
statePop = fileRead.substring(32,39);
regionNum = fileRead.substring(55,fileRead.length());
} // end constructor
public int getStatePop()
{
int population = Integer.parseInt(statePop);
return population;
} // #method getStatePop end method
public int getRegionNum()
{
int numOfRegion = Integer.parseInt(regionNum);
return numOfRegion;
}// end getRegionNum
public int getAvgPop()
{
int average = 2+2;
return average;
// total number of populations
// divide number of populations
}// #return the average population of states
public int getStateTotal()
{
//initialize static variable
int totalPopulation = 0;
int stateTotal = this.getStatePop() + totalPopulation;
return stateTotal;
} // #return stateTotal
public String toString()
{
return statePop + " " + stateNum + " ";
} // #method end toString method
} // end State class
The names of the columns (not used in the file read, just for explaining purposes) are:
State Capital Abbrev Population Region Nbr of Region
Washington Olympia WA 5689263West 6
Oregon Salem OR 3281974West 6
Massachusetts Boston MA 6147132New_England 1
Connecticut Hartford CT 3274069New_England 1
Rhode_Island Providence RI 988480New_England 1
New_York Albany NY18146200Middle_Atlantic2
Pennsylvania Harrisburg PA12001451Middle_Atlantic2
New_Jersey Trenton NJ 8115011Middle_Atlantic2
Maryland Annapolis MD 5134808Middle_Atlantic2
West_Virginia Charleston WV 1811156Middle_Atlantic2
Delaware Dover DE 743603Middle_Atlantic2
Virginia Richmond VA 6791345Middle_Atlantic2
South_Carolina Columbia SC 3835962South 3
Tennessee Nashville TN 5430621South 3
Maine Augusta ME 1244250New_England 1
Vermont Montpelier VT 588632New_England 1
New_Hampshire Concord NH 1185048New_England 1
Georgia Atlanta GA 7642207South 3
Florida Tallahassee FL14915980South 3
Alabama Montgomery AL 4351999South 3
Arkansas Little_Rock AR 2538303South 3
Louisiana Baton_Rouge LA 4368967South 3
Kentucky Frankfort KY 3936499South 3
Mississippi Jackson MS 2752092South 3
North_Carolina Raleigh NC 7546493South 3
California Sacramento CA32182118West 6
Idaho Boise ID 1228684West 6
Montana Helena MT 880453West 6
Wyoming Cheyenne WY 480907West 6
Nevada Carson_City NV 1746898West 6
Utah Salt_Lake_City UT 2099758West 6
Colorado Denver CO 3970971West 6
Alaska Juno AK 614010West 6
Hawaii Honolulu HI 1193001West 6
Am I on the right track here?
Thanks for any help in advance, and sorry for the long post!
The collections package would be useful here.
Create Map < Integer, List < < Integer > >
As you scan the file one line at a time, grab the region number and population.
Is the region number a key in the map?
No. Then create a new List < Integer > and add it to the map. Now it is.
Add the population to the list.
Now, the map should have four entries. Create the outer array like: int [ ] [ ] array = new int [ 4 ] [ ] ;
Then iterate over the lists in the map and populate the outer array like: array[i]=new int[list.size()];
Then iterate over the list and populate the inner array like: array[i][j]=list.get(j);
thanks for your quick response.
My professor hasn't gone over the Collections package yet (looking at some of the classes in the package, I think we'll go over those things next semester) so I'm not too familiar with the Map interface. Also, I think he wants us to use arrays specifically, although he did say that we could use ArrayList...
Up until I read your post, I was re-writing my code in another attempt to solve the problem. I'm going to look at the Map interface, but out of curiosity am I close with the following code? Seems like I just need to fix one line to correct my out of bounds error...
import java.util.*;
import java.io.*;
public class Main
{
public static void main(String[] args) throws IOException
{
// read in file States.txt, instantiate BufferedReader object,
// set new BufferedReader object to variable #newLine
FileReader f = new FileReader("States.txt");
BufferedReader br = new BufferedReader(f);
String newLine = br.readLine();
//declare jagged array
int[][] arrPopulation;
arrPopulation = new int[4][];
//create state object, and get
State newState = new State(newLine);
//read file
int col = 0;
arrPopulation[0] = new int[col];
arrPopulation[1] = new int[col];
arrPopulation[2] = new int[col];
arrPopulation[3] = new int[col];
int stateRegion = newState.getRegionNum();
while (newLine != null)
{
switch (stateRegion)
{
case 1:
arrPopulation[0][col] = newState.getStatePop();
System.out.println("Population added:" +
arrPopulation[0][col]);//test if col was created
col++; //increment columns
break;
case 2:
arrPopulation[1][col] = newState.getStatePop();
col++; //increment columns
break;
case 3:
arrPopulation[2][col] = newState.getStatePop();
col++;
break;
case 6:
arrPopulation[3][col] = newState.getStatePop();
System.out.println("Population added:" +
arrPopulation[3][col]);
col++; //increment columns
break;
}
br.readLine();
}//endwhile
br.close();//close stream
} // end public static void main
} // end main
Sorry if I'm supposed to place all this in the Comments section, however, I hit my character limit and couldn't post my code. Thanks again for your help!