Trouble handling input in Java - 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.

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.

My hashmap is only putting null values

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.

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.

Reading certain sentences from datafile.txt in java

In my program, it reads a file called datafile.txt... inside the datafile.txt is a random 3 lines of words. What my program does is reads the file the user types in and then they can type in a Line # and Word # and it will tell them the word that is in that location.. for example..
What is the file to read from?
datafile.txt
Please enter the line number and word number (the first line is 1).
2 2
The word is: the
My problem is that my program reads the 3 lines in the txt doc as 0, 1 ,2 and the words start from 0. So to read the first word in the first line they would have to type 0,0 instead of 1,1. What I am trying to do is make it work so they can type 1,1 instead of 0,0. Not sure what my problem is right now, here is my code....
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class readingFile {
/**
* #param args
* #throws IOException
* #throws validException
*/
public static void main(String[] args) throws IOException, checkException
{
System.out.println("Enter file name: " );
Scanner keyboard = new Scanner(System.in);
BufferedReader inputStream = null;
ArrayList<String> file = new ArrayList<String>();
String fileName = keyboard.next();
System.out.println ("The file " + fileName +
" has the following lines below: ");
System.out.println();
try
{
inputStream = new BufferedReader(new FileReader(fileName));
ArrayList<String> lines = new ArrayList<String>();
while(true)
{
String line = inputStream.readLine();
if(line ==null)
{
break;
}
Scanner itemnize = new Scanner(line);
while(itemnize.hasNext())
{
lines.add(itemnize.next());
}
lines.addAll(lines);
System.out.println(lines+"\n");
}
System.out.println("Please enter the line number and word number");
int index1 = keyboard.nextInt();
int index = keyboard.nextInt();
System.out.println("The word is: "+ lines.get(index));
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " + fileName);
}
inputStream.close();
}
private static void checkValid(ArrayList<String> items, int index) throws checkException
{
throw new checkException("Not Found");
}
}
The obvious solution to adapt 1-based user input to 0-based internal representation is to subtract one at some point. Seeing that you don't even use index1, writing
lines.get(index - 1)
isn't going to solve your problem completely. But I guess you can take it from there, and do something similar for the word index.
As I assume you are just learning to program I will point out 3 areas of improvement
Much like how mathematics has BIDMAS which determines the order of evaluation of an expression Java and other program languages evaluate statements in a particulate way. This means within the Parentheses of a function you may include a statment instead of a variable or constant. This will be evaluated with the result (or return) been passed into the called function. This is why MvG says you can do lines.get(index - 1)
Not all exceptions you should consider and plan around will the compiler inform you about. For example in your code an invalid input for line number or word number is entered you will get a Runtime Exception (array index out of bound)
Naming of variables should be useful, you have index and index1. What's the difference? I assume from reading your code one should be the user selected index of the line number and the second should be the index of the word on said line. May I suggest requestedLineIndex and requestedWordIndex.
On a final note this is not a usual StackOverflow question hence why your question has been 'voted down'. If you are learning as part of a course is there a course forum or Virtual Learning Environment (VLE) you can post questions on? The support of your peers at the same level of learning tends to help with exploring the basics of a language.

Read the first word of each line from a text file and then populate to Combo box

I have college project where i have to read the first word of every line from text file which looks as follow:
23123123213 Samuel classA
23423423423 Gina classC
23423423423 John classD
The text file will be updated with through 3 JTextField which i am able to figure out.
but now i have to populate the JCombobox with first word(23123123213,23423423423 and 23423423423) of all the lines.
I am new to java, i dont even have hint of how about doing it.
I know how to read and write to text files.
Please could someone help me do this?
The code so far i came up with is as follows:
import java.io.*;
public class FileRead
{
public static void main(String args[])
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("RokFile.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String[] delims = strLine.split(" ");
String first = delims[0];
System.out.println("First word: "+first);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
With u guys help I was successfully able to extract the first string from each line
but now how could i populate it in Jcombobox, I mean should i save it somewhere first?
Thanks in Advance
I'm not "down" with Java, however I can give you a few pointers:
You can read files, and presumably can read a line.
Each line is (presumably) separated with spaces so what you need to look up is a String.split function
Once you've split a string you will be able to use array index 0 to get the information you need.
Then it's just a case of adding split_string[0] to the JComboBox.
The documents are a great help:
String
JComboBox
You can get the first word using String.split(), or by using indexOf and substring.
There is a tutorial about JComboBox.
The Java Swing classes are based on Model/View, so you have to fill the strings into the Model of the JCombobox.
EDIT: In response to your edit, suppose you have retrieved the values. Then you can indeed save them to a specific data structure. It would be preferable to make the code that retrieves those values into a separate method. The values returned from that method (in, for example, a List<String>) can then be put into the JComboBox.
If you know how to read lines from a text file you can split each line by a delimiter, using the String.split function. In that case you get an array, with which you can get the first string by a normal array indexer, the [] operator that is.
String hello = "Hello world";
String[] delims = hello.split(" ");
String first = delims[0];
To answer your edit, you populate the JComboBox using one of its constructors, for instance the one that takes an Object array, or using the JComboBox.addItem(Object) function.
The latter has an example. Regarding the one with the constructor you can either build an array of objects yourself, or use an arraylist to which you add all your elements and then get an array using the ArrayList.toArray() function.

Categories