I am working on a problem and I am very stuck because I am just starting to learn java. Any help I can get to understand this would be great. I have to write a program that has two classes. The main class will read from a file and uses the second class to find how may times the same words have been repeated in the file and add them to an array that contans the words and number of times the word repeated. I am ok with the reading the file part. I just can't seem to wrap my head around how to call a method from the second class to add the word into the array and increment the counter.
Here is my code so far if you run it you will see how new I am to this by how many errors you will get.
import java.io.*;
public class Words{
public static void main (String [] args)
{
ProcessInput();
System.out.println("\nprogram finished");
}
public static WordList ProcessInput( )
{
BufferedReader inputFile;
String inputLine;
String[] word;
WordList words;
try
{
inputFile=new BufferedReader(new FileReader ("inputFile.txt"));
inputLine = inputFile.readLine();
while (inputLine !=null)
{
word=inputLine.toLowerCase().split(" ");
for (int i=0; i<word.length; i++){
System.out.println (word[i]);
words=addWord(word[i]);
}
inputLine = inputFile.readLine();
}
inputFile.close();
}
catch (IOException ioe)
{
System.out.println (ioe.getMessage());
ioe.printStackTrace ();
}
return words;
}
}
class WordList {
String [] words;
int wordcount;
public WordList ( ){
words= new String [1000];
wordcount=0;
}
public String addWord (String word) {
words[wordcount]=word;
wordcount=+1;
return words[wordcount];
}
public void printList (){
for (int i=0; i<wordcount; i++){
System.out.println (words[i]);
}
}
}
You're very close. What you need to remember is when you're calling a method from another class you need to tell the compiler where to find that method.
So, instead of simply calling addWord("someWord"), you will need to initialise an instance of the WordList class (e.g. WordList list = new WordList();), and then call the method using that (i.e. list.addWord("someWord");.
However, your code at the moment will still throw an error there, because that would be trying to call a non-static method from a static one. So, you could either make addWord() static, or change the methods in the Words class so that they're not static.
My bad with the above paragraph - however you might want to reconsider ProcessInput() being a static method - does it really need to be?
You have to initialise the object (create the object itself) in order to be able to call its methods otherwise you would get a NullPointerException.
WordList words = new WordList();
Related
I have a class Container where a user should be able to input any number of words until he types nothing. I have addWord(Word) method where each input is added to an ArrayList words every time do/while loop is run. I am passing user input value as a parameter to addWord() method each time loop runs.
Now I want to to display all elements of an array using display() method once the do/While loop has stopped running. But for some reason when i try to call method display(), it just shows an empty array [].
Is there any way you can help?
import java.util.ArrayList;
import java.util.List;
public class Container {
private List<String> words;
public Container() {
}
public List<String> getWords() {
return words;
}
public void setWords(List<String> words) {
this.words = words;
}
public void addWord(String word) {
words = new ArrayList<String>();
words.add(word);
}
public void display() {
System.out.println(words);
}
}
Main method:
import java.util.Scanner;
public class ContainerMain
{
public static void main(String[] args)
{
Container one = new Container();
Scanner myScan = new Scanner(System.in);
String word = "s";
do
{
word = myScan.nextLine();
one.addWord(word);
}
while (!word.equals(""));
if (word.equals("")) {
one.display();
}
else {
System.out.println("No hope fam");
}
}
}
Look at your addWord method:
public void addWord(String word) {
words = new ArrayList<String>();
words.add(word);
}
Each time you call that, it's going to create a new list - so you can never end up with more than one word in it.
The first line, initializing words, should be in your constructor (or as a field initializer). Then remove the line from addWord - ideally making the words field final at the same time, to avoid mistakes like this in the future, and remove the setWords method unless you really need it for something else.
That's all that wrong in Container (although it's not clear that it's really providing any value beyond just using a List<String> directly). As noted in comments, currently your do/while loop in main will add an empty string at the end. Also, there's no point in checking whether word is empty or not after the loop - it has to be, otherwise you wouldn't have exited the loop!
I made a class that reads a text file into an integer array, which I believe I've done correctly. Then I wanted to make a method (getInt();) within that to get the the first index of the array, and then each time it gets called get the following index element.
I had the idea to increment it every time it gets called to get the following index element, but the main problem I am having is that I cannot access my list outside of the try statement and I am therefore unable to make a method for it.
Can anyone suggest a piece of code or any advice on how to create this method?
import java.io.*;
import java.util.*;
public class ScannerIntegerList {
public static void main(String[] args) {
try {
FileReader file = new FileReader("file.txt");
BufferedReader input = new BufferedReader(file);
List<Integer> list = new ArrayList<Integer>();
String temp = "";
while ((temp = input.readLine()) != null)
if (!temp.trim().equals("0"))
list.add(new Integer(temp));
input.close();
int i = 0;
System.out.println(list.get(i));
i++;
} catch (IOException ie) {
System.out.println(ie);
}
}
}
Also as a side note I am using eclipse and whenever I try and remove public static void main( String [] args) it tells me I need it, can anyone explain why this happens and how I can get around it, specifically with this bit of code?
When this class is finished the filename will also come from the command line so any advice on this would be greatly appreciated.
Many thanks in advance
If you want to use list outside the try block, declare and initialize it outside.
Also, use try-with-resources when working with closeable resources, like this:
List<Integer> list = new ArrayList<>();
try (BufferedReader input = new BufferedReader(new FileReader("file.txt"))) {
String temp = "";
while ((temp = input.readLine()) != null) {
if (!temp.trim().equals("0")) {
list.add(new Integer(temp));
}
}
} catch (IOException e) {
e.printStackTrace();
}
// you can use list here, knock yourself out
If the filename will come from the command line,
then you really need the public static void main(String[] args) method.
Your program will receive command line arguments in the args array.
If the filename is the first command line argument,
you can use it via args[0].
Edit
Many users are commenting that the Class Word is useless, which is probably true in this case. The reason I added it, is because I need it later on in the program.
This program has 3 classes - WordList, Word and a test class. I'm trying to get the method 'readBook' to read through a file, and send every word over to the method 'addWord'. Method addWord will check if the ArrayList allWords contains that word. If it doesn't, addWord will then add the word to an array, aswell as to send it over to class Word. When I run the program, nothing happens. I tried to print out allWords.size(), which returned 0.
Class WordList:
public class WordList {
String nextWord;
ArrayList<String> allWords = new ArrayList<String>();
public void readBook (String filename) throws Exception{
File file = new File(filename); //File has one word on each line.
Scanner innFile = new Scanner(file);
for (int i = 0; i<file.length(); i++){
if(innFile.hasNextLine()){
nextWord = innFile.nextLine();
addWord(nextWord);
}
}
}
private void addWord(String word){
for (String check : allWords){
if (!check.equalsIgnoreCase(word)){
allWords.add(word);
new Word(word);
}
else if(check.equalsIgnoreCase(word)){
System.out.println("The word allready exsist.");
}
else{
System.out.println("Something went wrong.");
}
}
}
Class Word:
public class Word {
String word;
ArrayList<String> allWords = new ArrayList<String>();
Word(String text){
word = text;
allWords.add(word);
System.out.print(allWords);
}
The test class:
public class TestClass {
public static void main (String[] args) throws Exception{
WordList list = new WordList();
list.readBook("path.../scarlet.text");
WordList newList = new WordList();
System.out.println(newList.numberOfWords());//A method printing out allWords.size()
}
}
You are populating allWords list of WordList class inside for (String check : allWords). Initially it would be empty hence it will never enter the for loop and allWords will never get populated. In turn new Word(word) will not be called and allWords of word class will be empty.
You have two issues with your code.
First, when that main loop (for (String check : allWords)) runs, allWords is going to be empty. Therefore, you will never add any elements to it, and that means it will always have a size of 0. To correct this, you probably need to add a boolean variable that gets set to true if you find the word. Then, after the loop, if the boolean variable is still false, add the word to the list.
Secondly, you've got allWords defined on two places: in your WordList class, and in your Word class. The WordList.allWords array is being updated correctly (as far as I can tell, once you fix the above mentioned issue). However, the Word.allWords array is not doing anything other than storing a single String value... twice (once in the array, once in a variable). The Word class isn't really doing anything useful, so I would opt to get rid of it.
I would get rid of the Word class completely, since it's currently not doing anything other than storing a String, which you could do with a String variable.
When the method addWord(String) is called it never enters the for loop because allWords is initially an empty ArrayList. Your call to "new Word(String)" is never reached.
I don't think you need allWords in both the Word class and the WordList class (?)
If you're just trying to get the unique words you can do this:
Set<String> words = new LinkedHashSet<>();
File file = new File("some file");
Scanner inFile = new Scanner(file);
for (int i = 0; i < file.length(); i++)
if (inFile.hasNextLine())
words.add(inFile.nextLine());
inFile.close();
then call
words.size()
to check if an array list contains a certain string you can use a for loop.
I'm not sure if this is the best way to go about it, but it should work.
for(int i = 0; i<yourArrayList.size(); i++){
if (yourArrayList.get(i).!contains(yourString)){
yourArrayList.add(yourString);
}
In test class try:
public static void main(String[] agrs) throws Exception {
WordList w = new WordList();
w.readBook("pathToMyFile"); // This way you access to readBook method
....
}
And add the word in method addWord when attribute allWords is empty.
private void addWord(String word){
if (allWords.isEmpty()) {
allWords.add(word);
} else {
// Your code
}
}
I have a problem creating a student class which contains a constructor which takes a Scanner string of a format "Brookes 00918 X12 X14 X16 X21". The conditions should be that there should be a student name and student number and the course codes should start with an "X". I have thrown IncorrectFormatExceptions in the case that they are not satisfied. However when I create a test class and enter a string and press enter , for example "abc 123" it doesn't produce an output which is usually the case.
Update: I've changed the code to use a String array tokens however now with the toString() method using "123 abc X12" it gives a Null Pointer Exception. It works when I put "123 abc" in the constructor
Update:Seems to work now forgot to initialize the arrayList
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Student extends UniversityPerson{
private String studentNumber="";
private List<String> courses=new ArrayList<String>();
private String studentName="";
public int checkNoofletters(char[] chararray){
int noofletters=0;
for (char c:chararray){
if (Character.isLetter(c)){
noofletters++;
}
}
return noofletters;
}
public String courseListinStr(){
String stringo="";
for (String c:courses){
stringo+=c;
stringo+=" ";
}
return stringo;
}
public Student(Scanner scanner) throws IncorrectFormatException{
int studentNumberCount=0;
int studentNameCount=0;
Scanner s=scanner;
String input=s.nextLine();
String[] tokens=input.split("\\s");
for (int i=0; i<tokens.length; i++){
char[] chars=tokens[i].toCharArray();
if (checkNoofletters(chars)==chars.length){//if the number of letters is equal to the character length
if (studentNameCount==1){throw new IncorrectFormatException("Can only have 1 student name");}
studentNameCount++;
this.studentName=tokens[i];
continue;
}
if (tokens[i].matches("[0-9]+")){//add to the studentNumbers list
if (studentNumberCount==1){throw new IncorrectFormatException("Can only have 1 student number");}
studentNumberCount++;
this.studentNumber=tokens[i];
continue;
}
if (!tokens[i].startsWith("X")){
throw new IncorrectFormatException("Course code must start with an 'X'");
}
System.out.println(tokens[i]);
courses.add(tokens[i]);
}
if (studentNumber=="" || studentName==""){
throw new IncorrectFormatException("Must have 1 student Number and Student Name");
}
}
#Override
public String toString() {
//return String.format("%s %s", studentName,courseListinStr());
return String.format("Student: %s %s", studentName,studentNumber);
}
#Override
public boolean equals(Object o) {
// TODO Auto-generated method stub
return false;
}
}
The best way would be to do something like this:
Scanner s=scanner;
String input = s.nextLine();
String[] tokens=input.split("\\s");
Now you can test all your conditions:
if (tokens.size() < yourNumber) throw new Exception("add here");
if (tokens[2].charAt(0)!='X') throw new Exception("add here");
and so on; it should be rather easy to create your Student Object based on your requirements.
Your program is full of errors and I'll list some of them after answering why it doesn't print anything: if you dump all threads you'll see that the main thread is stuck at next(), which blocks until next token is available, and effectively never leaves the constructor of the first student
if (s.hasNextInt()){
studentNumbers.add(s.nextInt());
s.next();
continue; // <--------- this line
}
I think this is not the only error in your program, so maybe you'd better throw the entire parsing away and restart from scratch.
You should create exactly one Scanner object for each input stream, not one for parsed object
You should not pass the scanner to the Student constructor
You should not put any algorithm in a constructor: make a separate object instead
To simplify your program introduce a Parser class
public class Parser {
public Parser(Reader in) {}
public boolean hasNext() {}
public Student next() {}
}
and inside next() make the parser deal with entire lines (Scanner.hasNextLine and Scanner.nextLine()) instead of individual tokens, otherwise you'll have to define a custom protocol to mean EOR (end of record)
Dealing with lines is easier to think about, program and test. Once you have the full record, you can further tokenize it with a simple String.split(), or directly use regular expressions.
I didn't go through, your whole code. But, I would suggest you to use StringTokenizer or split function and store it in temp array. Then, traverse through your temp array and validate the data.
I'm pretty new to programming feel free to be harsh in your replies. Anything helps.
Basically I'm trying to call in a method LineCount() but when I try to compile the command prompt complains about .class being expected at String[A] (line 8 I believe)
*Thank you guys for all your help! My code works now! I really appreciate all the input
import java.util.Scanner;
import java.io.*;
public class FileCount{
public static void main(String[] args) throws IOException{
String[] in = new Scanner(new File(args[0]));
System.out.println(lineCount(String[] in);
}
public static void lineCount(String[] A){
// check number of command line arguments
if(args.length != 1){
System.err.println("Usage: LineCount file");
System.exit(1);
}
// count lines, words, and chars in file
int lineCount = 0;
while( in.hasNextLine() ){
in.nextLine();
lineCount++;
}
in.close();
System.out.println( args[0]+" contains "+lineCount+" lines" );
}
}
First of all
System.out.println(lineCount(String[] in); // this is incomplete need to close)
Assuming you did mistake while you putting the question here, Change
System.out.println(lineCount(String[] in));
To
System.out.println(lineCount(in));
-> There are many mistakes in your code, Besides other answers want to add that, Since you are passing lineCount(in) as an argument to the linecount() method , then refer to the parameter in lineCount(String[] A) now via A variable and not in.
-> Also you cannot refer to args inside linecount() method since it is a parameter of main() method and hence is limited to it in its scope.
-> You cannot do this String[] in = new Scanner(new File(args[0])); , you are assigning a Scanner instance to an String Array, you have to do it like this
Scanner in = new Scanner(new File(args[0]));
-> You are calling linecount() inside a System.out.println() method , although your method linecount() has a return type of void, Dont put your method inside print() function , because anyways it has got print() statements inside it.
-> Maybe last , there could be more , Since your in variable is of type Scanner , change your method declaration to
public static void lineCount(Scanner in){
and now call it like lineCount(in) from main().
Edit :- Since you are a beginner i will give you working code for your question:-
import java.util.Scanner;
import java.io.*;
public class FileCount{
public static void main(String[] args) throws IOException{
// check number of command line arguments, and check it in main()
if(args.length != 1){
System.err.println("Usage: LineCount file");
System.exit(1);
}
Scanner in = new Scanner(new File(args[0]));
System.out.println( args[0]+" contains "+lineCount(in)+" lines" ); //call this line in main() and not in linecount() as you refer to both args and need the linecount.
}
public static int lineCount(Scanner in){
// count lines, words, and chars in file
int lineCount = 0;
while( in.hasNextLine() ){
in.nextLine();
lineCount++;
}
in.close();
return lineCount; //return the linecount from method
}
}
Your first problem String[] in = new Scanner(new File(args[0])); creating a Scanner object and asigning it to an array it does not work like this. Change your code to read the file and store it in some arraylist like
List<String> list= new ArrayList<String>();
Scanner in = new Scanner(new File(args[0]));
while (in.hasNextLine()) {
// find next line
String line = in.nextLine();
list.add(line);
}
Then if you want can convert to list to String array which is not really necessary like this
String[] strArr = list.toArray(new String[0]);
System.out.println(java.util.Arrays.toString(strArr));
lineCount(strArr);
Then call the lineCount() method which counts the lines in the files.
public static void lineCount(String[] A){
System.out.println("File contains "+A.length+" lines" );
}