My hashmap is only putting null values - java

To help myself learn java, i am creating a blackjack program using a JForm GUI that include accounts that you can create and keep a running balance you use to bet on each game. I have a BlackJackApp.JForm class which is the main class. The accounts are stored in a .txt file and are read using an Account class containing readFile and writeFile methods. I created a sample txt file, named Accounts.txt, with these values:
John Doe>>1000000
Jack Black>>1
Bob Dole>>987654321
(there are no empty spaces between lines in the actual txt file)
I have a method that reads the text file and attaches these values to a HashMap. This is the code i have for the method.
public void readFile()
{
accountsMap.clear();
BufferedReader br;
try
{
br = new BufferedReader(new FileReader("Accounts.txt"));
String nextLine = br.readLine();
while(nextLine != null)
{
String lineString[] = nextLine.split(">>");
Integer accountBalance = Integer.parseInt(lineString[1]);
System.out.println(lineString[0] + " " + lineString[1] + " " +
accountBalance);
accountsMap.put(lineString[0], accountBalance);
nextLine = br.readLine();
}
br.close();
}
catch(IOException frex)
{System.out.println("An error has occurred while reading the file");}
}
This is the relevant code i have for the JForm class, with only the top portion included for reference
public class BlackjackApp extends javax.swing.JFrame {
Account a = new Account();
String account;
Integer accountBalance;
HashMap accountsMap = a.getAccountsMap();
public void fillAccountNameBox()
{
for (int i = 0; i < accountsMap.size(); i++)
{
accountNameBox.addItem((String) accountsMap.get(i));
}
}
public BlackjackApp() {
initComponents();
a.readFile();
fillAccountNameBox(); //fills comboBox component w/ list of hashMap keys
System.out.println(accountsMap.keySet());
for(int i = 0; i < accountsMap.size(); i++)
System.out.println(accountsMap.get(i));
}
The system.out.println code is for debugging. This is the output:
John Doe 1000000 1000000
Jack Black 1 1
Bob Dole 987654321 987654321
[Bob Dole, John Doe, Jack Black]
null
null
null
My question is this: why is my hashmap putting in the correct keys, but leaving their values null? The lineString array is populating correctly, and so is the Integer accountBalance, but when it comes to actually putting the key/value pairs into the hashmap, it only puts the keys in and it leaves their values null even though accountBalance is not null. Why is this? I have tried searching numerous threads for advice relating to this issue but none of their advice worked for me. There must be something that im overlooking, but as a beginner its hard for me to recognize where the problem lies.

The problem relys on the way you are printing the information.
The Map.get method expects you pass a parameter with a key, whose value you want. In the for loop, you are asking for the values attached to the keys 0, 1 and 2 - hence the null values.
Change your code to this:
for(String key : accountsMap.keySet())
System.out.println(accountsMap.get(key));
As you can see, I also changed the for loop structure to use a for-each.
Hope this helps you.

Your map contains exactly what you want it to contain. The issue is how you are accessing it.
As you have pointed out, the keys in your map are as follows:
[Bob Dole, John Doe, Jack Black]
In your final for loop, you are looking to access the values mapped to keys 0, 1 and 2. As these keys don't exist in your map, you will get null.

Related

How to get information from a CSV file in Java

I have a .CSV file with rows for [ID], [NAME], [LASTNAME], [EMAIL], [GENDER]. There are 1000 entries.
Out of those five rows I have to:
Find the total of people on the list. (using a for loop?)
Show the first 10 names (name, lastname).
Show 3 RANDOM names.
Only display emails. (Doable with the current code)
Display the first letters of their last name.
Add a random number behind their last name.
Can someone make an example, please?
As a Java beginner I really can't seem to find an answer to this. I have searched everywhere and i think im going crazy.
I have imported the .csv file to my java eclipse, using the following code, currently it only displays the ID's.
package test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class test111 {
public static void main(String[] args) {
String fileName="test.csv";
File file = new File(fileName);
try {
Scanner inputStream = new Scanner(file);
inputStream.next();
while (inputStream.hasNext()) {
String data = inputStream.next();
String[] values = data.split(",");
System.out.println(values[0]);
}
inputStream.close();
System.out.println("e");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
In order to take every value you have to do something like this:
int id = Integer.parseInt(values[0]);
String name = values[1];
String lastName = values[2];
String email = values[3];
String gender = values[4];
Yours is a lesson in why you shouldn't blindly copy code without reading it, researching it and understanding it.
Look at line 15 from your own code. What do you think is going on here?
String[] values = data.split(",");
You've read a line from your CSV file into a field called data and now you're calling the .split method with a comma as a parameter to break up that line into tokens wherever it finds a comma. Those tokens are being placed into the cells of an array called values.
Why are you only getting your ID attribute? Look at this line:
System.out.println(values[0]);
We just established that all tokens have been placed in an array called values. Let's look at the attribute key you provided:
[ID], [NAME], [LASTNAME], [EMAIL], [GENDER]
Hmm... if printing values[0] gives us the ID, I wonder what we'd get if we... oh, I don't know... maybe tried to print from a different element in the array?
Try:
System.out.println(values[1]);
System.out.println(values[2]);
System.out.println(values[3]);
System.out.println(values[4]);
See what you get.
Coding is about trying things in order to learn them. Knowledge doesn't magically become embedded in your head. To learn something, you have to practice repeatedly, and in doing so, you're going to make mistakes -- this is just how it goes. Don't give up so easily.

Altering input for HashMap in Java using split() method with array without crashing

working on my current lab and seemed to have run into a slight roadblock. I have never used the split() method up until now and am unsure on how to remedy my problem. Here is a snippet of my code to get started explaining.
Map<Integer, Employee> employeeMap = new HashMap<>();
while (true)
{
line = scanner.nextLine();
if (line.startsWith("$"))
{
break;
}
String[] employeeTracker = line.split(" ");
Employee employee = new Employee(
++empCount,
employeeTracker[0],
employeeTracker[1],
employeeTracker[2],
Double.parseDouble(employeeTracker[3]),
Integer.parseInt(employeeTracker[4]), Boolean.parseBoolean(employeeTracker[5]));
employeeMap.put(employee.getId(), employee);
}
Original example input: (this was when my Employee employee = new Employee had 4 arguments for input. I have now increased it to 6 for 2 additional inputs needed from a new class being added.
John Smith 1234567 10.55
New input I'm trying to get to work.
*John Smith 1234567 10.55 1 true
The issue currently is now that I have made the program accept this new input, I need it to also just work when the old type of input is put in (with just 4 arguments). My first thought is to give some dummy value to those other 2 last arguments when this occurs to prevent crashing, but I have had little luck doing so. Thus, I search for any welcoming suggestions.
Thanks in advance! I would be glad to post any additional code or answer any other questions as necessary.
You can use the length of the employeeTracker array to test what the input is
if (employeeTracker.length >= 6) {
// new inoput
}
else {
// old input
// use dummy values
}

Scanning from a text document

So I have an assignment from an online course to create a program that can scan a massive document. What this document contains is hundreds of pairs of letters that include GB GG BB BG and each set of two letters has its own line. What I have to do is figure out how many lines there are and then figure out how many of the different sets of two letters there are. I've attempted the code but I am currently stuck. The code that I have compiles but when I run it in BlueJ an output window doesn't even pop up. This is what I have so far:
/**
* This program sorts through a file and
* determines the composition of various families.
* Timothy Pierce
* 1/2/2016
*/
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Family
{
public static void main(String [ ] args) throws IOException
{
boolean isTwoBoys;
boolean isTwoGirls;
boolean isBoyGirl;
int twoBoysCounter = 1;
int twoGirlsCounter = 1;
int boyGirlCounter = 1;
String line = "";
Scanner inFile = new Scanner(new File ("C:\\Users\\TEM\\Desktop\\Projects\\Family\\Document\\test1.txt"));
while (inFile.hasNextLine ())
{
isTwoBoys = (line.equals("BB"));
isTwoGirls = (line.equals("GG"));
isBoyGirl = (line.equals("BG")||line.equals("GB"));
if(isTwoBoys)
{
twoBoysCounter++;
}
else if(isTwoGirls)
{
twoGirlsCounter++;
}
else if(isBoyGirl)
{
boyGirlCounter++;
}
}
System.out.println();
System.out.println("Two Boys: " + twoBoysCounter);
System.out.println("One Boy One Girl: " + boyGirlCounter);
System.out.println("Two Girls: " + twoGirlsCounter);
inFile.close();
}
}
I've tried for several hours but I cant seem to get it to work. I haven't even been able to count how many line there are. Any help would be very appreciated! Thanks!
You never read the next line, so you're stuck in an infinite while loop
I suggest that you look into Files.readAllLines function for this case.
It loads all the lines in a List over which you can easily iterate and do what you need.
Example: Files.readAllLines(Paths.get("C:\\Users\\TEM\\Desktop\\Projects\\Family\\Document\\test1.txt", Charsets.default()) will load what you need
your while loop is inifinite as stated above since inFile.hasNextLine () is a boolean statement that returns true or false but it doesnt advance the scanner to the next line, you need to add to each of the if statements a :
inFile.nextLine() //advance the inputstream
Skipping over the "no readNextLine" issue pointed out by others, your basic technique is terrible.
Use a Map<String, Integer>.
Store the character pair as the key.
Every time you read a new pair,
attempt to retrieve it from the map.
If you get null, then the pair does not already have a counter,
so store 1 as the value.
If you get a non-null value, add 1 and store the new count.
When finished reading,
you have a map of character pairs to number of times encountered.

I need to store each entered line into the same array

I need to store multiple lines of input into the same array. The loop has to continue storing each new line into the array until a sentinel value is typed in. So far, I have this code:
while(!students.equals("zzzz") && !students.equals("ZZZZ")){
students = br.readLine();
studentInfo = students.split("\\n");
}
System.out.println (studentInfo[0]);
All this does when I type the sentinel value (either ZZZZ or zzzz) is print out zzzz at the end because it stores the sentinel value into the first array location. What am I missing? Id like to be able to type any number of lines, and access each one of those lines and manipulate the string by calling on it (studentInfo[5] or studentInfo[55]). Please help
By definition, br.readLine() will not return anything with a newline character, so this code:
students = br.readLine();
studentInfo = students.split("\\n");
will always result in studentInfo being an array of size 1, whose first (and only) element is whatever is in students.
Further, you are replacing studentInfo every loop, so it always has the last line entered, which logically must be "zzzz" or "ZZZZ".
To fix the problem, you should use a List, which can grow in size automatically (basically you should avoid using arrays).
Try this:
List<String> studentInfo = new LinkedList<>();
String student = "";
while (!student.equalsIgnoreCase("zzzz")) {
student = br.readLine();
if (!student.equalsIgnoreCase("zzzz"))
studentInfo.add(student);
}
System.out.println (studentInfo);
The while loop is a little clumsy, because the student variable must be declared outside the loop (even though it's only needed in the loop) and the condition must be repeated (otherwise your data will contain the terminating signal value).
It can be expressed better as a for loop:
for (String student = br.readLine(); !student.equalsIgnoreCase("zzzz"); student = br.readLine())
studentInfo.add(student);
Note also the use of equalsIgnoreCase() for the string comparison.
I have made slight changes to your code and added comments on how this can be done:
List<String> studentInfo = new ArrayList<>(); //use arraylist since you don't know how many students you are expecting
//read the first line
String line = ""; //add line reading logic e.g. br.readLine();
while(!line.equalsIgnoreCase("zzzz")){ //check for your sentinel value
line = br.readLine(); //read other lines
//you can add an if statment to avoid adding zzzz to the list
studentInfo.add(students);
}
System.out.println("Total students in list is: " + studentInfo.size());
System.out.println (studentInfo); //print all students in list
System.out.println (studentInfo.get(29)); //print student 30

Trouble handling input in Java

I'm trying to read input from the terminal. For this, I'm using a BufferedReader. Here's my code.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] args;
do {
System.out.println(stateManager.currentState().toString());
System.out.print("> ");
args = reader.readLine().split(" ");
// user inputs "Hello World"
} while (args[0].equals(""));
Somewhere else in my code I have a HashTable where the Key and Values are both Strings. Here's the problem:
If I want to get a value from the HashTable where the key I'm using to look up in the HashTable is one of the args elements. These args are weird. If the user enters two arguments (the first one is a command, the second is what the user wants to look up) I can't find a match.
For example, if the HashTable contains the following values:
[ {"Hello":"World"}, {"One":"1"}, {"Two":"2"} ]
and the user enters:
get Hello
My code doesn't return "World".
So I used the debugger (using Eclipse) to see what's inside of args. I found that args[1] contains "Hello" but inside args[1] there is a field named value which has the value ['g','e','t',' ','H','e','l','l','o'].
The same goes for args[0]. It contains "get" but the field value contains ['g','e','t',' ','H','e','l','l','o']!
What the hell!!!
However, if I check my HashTable, wherever the key is "Hello", the value=['H','e','l','l','o'].
Any ideas?
Thank you very much.
EDIT:
Here's come code sample. The same is still happening.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
public class InputTest
{
public static void main(String[] args)
{
BufferedReader reader = new BufferedReader(new InputStreamReader( System.in));
Hashtable<String, String> EngToSpa = new Hashtable<String, String>();
// Adding some elements to the Eng-Spa dictionary
EngToSpa.put("Hello", "Hola");
EngToSpa.put("Science", "Ciencia");
EngToSpa.put("Red", "Rojo");
// Reads input. We are interested in everything after the first argument
do
{
System.out.print("> ");
try
{
args = reader.readLine().trim().split("\\s");
} catch (IOException e)
{
e.printStackTrace();
}
} while (args[0].equals("") || args.length < 2);
// ^ We don't want empty input or less than 2 args.
// Lets go get something in the dictionary
System.out.println("Testing arguments");
if (!EngToSpa.contains(args[1]))
System.out.println("Word not found!");
else
System.out.println(EngToSpa.get(args[1]));
// Now we are testing the word "Hello" directly
System.out.println("Testing 'Hello'");
if (!EngToSpa.contains("Hello"))
System.out.println("Word not found!");
else
System.out.println(EngToSpa.get("Hello"));
}
}
The same is still happening. I must be misunderstanding Hash Tables. Ideas where things are going wrong?
Don't worry about the value field - that's just saying that there's a single char array containing the text of "get Hello", and both args[0] and args[1] refer to that char array, but they'll have different offsets and counts. args[0] will have an offset of 0 and a count of 3; args[1] will have an offset of 4 and a count of 5.
I've no idea why your hash map wouldn't be working though... can you provide a short but complete example program?
I just noticed my mistake. I have to use containsKey() instead of contains().
I'd like to thank everyone for helping.
As a bonus, I also learned about what the 'value' field is. Nice!
As Jon said, you're just seeing an artifact of the internal implementation of Strings in Java. You can ignore the value field for your purposes. That has nothing to do with why things aren't working for you. You need to show us the part of the code that's not working.

Categories