Below is an example of my code. I have a text file called dictionary.txt that I am trying to read from and I keep getting an error in the constructor line. I am unsure how to build the constructor to read the dictionary.txt file and how that interacts with name = new File("dictionary.txt");
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class WordLists{
//instance variables
private String[] words; //array of words taken in
private int wordCount;
private File name;
private Boolean hasLetter;
//constructor
public WordLists(String "WHAT GOES HERE?") throws FileNotFoundException {
//throws exception because it takes and scans a file
wordCount=0;
name=new File("dictionary.txt");
hasLetter=null;
Scanner listScanner=new Scanner(name);
while(listScanner.hasNextLine()){
listScanner.nextLine();
wordCount++;
}
listScanner.close();
words=new String [wordCount];
Scanner secondScanner=new Scanner(name);
for(int i=0; i<wordCount; i++){
words[i]=secondScanner.nextLine();
}
secondScanner.close();
}
Instead of saying it throws a file not found exception in the constructor, say it at the class name. If that doesn’t work, try a try catch syntax instead of throwing an exception in the class
The String in the constructor line should be a variable corresponding to the file path of the .txt file you're trying to read.
Additionally, work on formatting your code to make it easier to read. With formatting, adding in the string variable to the constructor, and then a main method to run the whole thing, the finished class should look something like this:
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class WordLists {
//instance variables
private String[] words; //array of words taken in
private int wordCount;
private File name;
private Boolean hasLetter;
Scanner listScanner, secondScanner;
//constructor
public WordLists(String path) throws FileNotFoundException{
//throws exception because it takes and scans a file
wordCount = 0;
name = new File(path);
hasLetter = false;
listScanner = new Scanner(name);
secondScanner = new Scanner(name);
while(listScanner.hasNextLine()){
listScanner.nextLine();
wordCount++;
}
words = new String [wordCount];
for(int i = 0; i < wordCount; i++){
words[i] = secondScanner.nextLine();
}
listScanner.close();
secondScanner.close();
}
public static void main(String[] args){
try {
WordLists w = new WordLists("dictionary.txt");
}catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("Done");
}
}
Related
I am attempting to read a text file that I created using another code to fill out a map however the scanner keeps on stopping early, however if I remove the line in the text doc where it stops the scanner will continue on for a while before getting stuck again. I can't see why it would be getting stuck on certain lines though. I added a link to the text doc that I am scanning through. For instance no matter when it is written the first instance of the castlevania line will clog up the system, in the doc it shows up at line 307. If that line is removed it crahses at stops at Conta on line 383. Then if that is removed it breaks at Dig Dug on line 479. It continues in this way of stopping on random lines that seem to have no relation, in name or line number.
TextDocDownload
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
public class Read {
public static PrintWriter writer;
public static Map<String, LinkedHashMap<String, String>> connectionsMap = new LinkedHashMap<String, LinkedHashMap<String,String>>() ;
public static void main(String[] args) {
setUp();
Iterator it = connectionsMap.entrySet().iterator();
int i =0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() +" "+i);
i++;
it.remove(); // avoids a ConcurrentModificationException
}
}
public static void setUp() {
File file = new File("Degrees.txt");//file with all the connections
try {
Scanner scanner = new Scanner(file);
String description = "";
String key="";//key for map of main series
String secondKey="";//key for map of a mian serieses connections
String text = "";
while(scanner.hasNext()) {
String see = scanner.next();
if(see.equals("TITLEEND")) {
key=text;
text="";
}
if(see.equals("CONNECTIONTITLEEND")) {
secondKey=text;
text="";
}
if(see.equals("DESCRIPTIONEND")||see.equals("TERMINATE")) {
description =text;
text="";
mapMaker(key,secondKey,description, false);
}if(!see.equals("TERMINATE")&&!see.equals("CONNECTIONTITLEEND")&&!see.equals("DESCRIPTIONEND")&&!see.equals("TITLEEND")) {
if(text.length()<1)text=see;
else text+=" "+see;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void mapMaker(String key, String secondKey, String description, boolean recursed) {
if(!connectionsMap.containsKey(key)) {
connectionsMap.put(key, new LinkedHashMap<String,String>());
}if(!connectionsMap.get(key).containsKey(secondKey)) {
connectionsMap.get(key).put(secondKey, description);
}
if(!recursed) {
mapMaker(secondKey,key,description,true);
}
}
I have an assignment for school that's all about using files, HashMap and ArrayList. This assignment requires 4 classes.
The first class is called FileReader and reads a txt file which is written line by line and each field that we need is separated by ";", for example ("Columbia University";"USA";78.86;2012). Each line contains 2 strings (university name and country) and 2 numbers (score and year). The FileReader class after reading the txt file returns its content in an arraylist.
The second class of the assignment is called UniversityScores and it has 4 fields (uniname, country, score, year), a constructor, accessor methods for all fields and a toString method.
The third class is the heart of our program. This class is called FileEditor and creates a Hashmap<Integer,ArrayList<UniversityScores>> where the key is the year field of each object and value I guess is the rest of the line. My problem is filling the right way the HashMap.
Also, my final 4th class is called FileWriter which creates a new txt and writes inside of it. All my classes work as supposed to except my FileEditor class. Any help needed. Thank you in advance!
Edit
I am supposed to write some other methods as well. For now my problem is the FileEditor class. I also posted the TestFiles class which contains the main function.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
class FileReader{
private String fileName;
private Scanner scanner;
private File file;
private ArrayList<String> arrayList;
private String line;
public FileReader(String otherFileName){
this.fileName = otherFileName;
this.file = new File(fileName);
}
public boolean initReader(){
try {
scanner = new Scanner(file);
}
catch (FileNotFoundException e) {
System.out.println("Just caught a FileNotFoundException.");
}
if(file.exists()){
return true;
}
else{
return false;
}
}
public ArrayList<String> readFile(){
this.arrayList = new ArrayList<String>();
while (scanner.hasNextLine()) {
this.line = scanner.nextLine();
arrayList.add(line);
}
arrayList.remove(0);
//System.out.println(arrayList);
return arrayList;
}
public void closeReader(){
scanner.close();
System.out.println("Scanner closed");
}
}
import java.util.ArrayList;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class FileWriter{
private String path;
private PrintWriter writer;
private File outputFile;
public FileWriter(String otherPath){
this.path = otherPath;
this.outputFile = new File(path);
}
public boolean initWriter(){
try{
writer = new PrintWriter(path);
}
catch (FileNotFoundException e){
System.out.println("just caught an exception");
}
if(outputFile.exists()){
return true;
}
else{
return false;
}
}
public void writeFile(){
writer.println("The first line");
writer.println("The second line");
writer.println("Christos");
}
public void closeWriter(){
writer.close();
System.out.println("Writer closed");
}
}
class UniversityScore{
private String name;
private String country;
private double score;
private int year;
public UniversityScore(String otherName, String otherCountry, double otherScore, int otherYear){
this.name = otherName;
this.country = otherCountry;
this.score = otherScore;
this.year = otherYear;
}
public String getName(){
return name;
}
public String getCountry(){
return country;
}
public double getScore(){
return score;
}
public int getYear(){
return year;
}
public String toString(){
String outputString = name + "\t" + country + "\t" + score + "\t" + year;
return outputString;
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
class FileEditor{
private HashMap<Integer, ArrayList<UniversityScore>> scores = new HashMap<Integer, ArrayList<UniversityScore>>();
private ArrayList<String> lines;
public FileEditor(ArrayList<String> otherLines){
this.lines = otherLines;
}
public void fillHashMap(){
// that's where I need help
}
}
public class TestFiles {
public static void main(String[] args){
FileReader reader = new FileReader("universities.txt");
if(reader.initReader()){
FileEditor editor = new FileEditor(reader.readFile());
reader.closeReader();
editor.fillHashMap();
FileWriter writer = new FileWriter("universities_2015_output.txt");
if(writer.initWriter()){
writer.writeFile(editor.getScoresOfYear(2015));
writer.closeWriter();
}
else{
System.out.println("Error creating file");
}
System.out.println("Average university score of year 2015: "+editor.getAverageOfYear(2015));
System.out.println("Min university score of year 2015: "+editor.getMinOfYear(2015));
System.out.println("Max university score of year 2015: "+editor.getMaxOfYear(2015));
}
else{
System.out.println("Error opening file");
}
}
}
You will need a way to parse your lines into UniversityScore objects.
Now that you have all the scores, you can add it to your map, according to their year values (may be score but the type doesn't match nor makes practical sense), for example:
for(String line : lines){
String[] vals = line.split(";");
UniversityScore score = new UniversityScore(vals[0],vals[1],Double.parseDouble(vals[2]),Integer.parseInt(vals[3]))
if(scores.containsKey(score.getYear()){ // If the key exists
scores.get(score.getYear()).add(score);
}else{ // If the key doesn't exist, it must be created and added to the map
ArrayList<UniversityScore> newList = new ArrayList<>();
newList.add(score);
scores.put(score.getYear(), newList)
}
}
I noticed your map has an Integer key which corresponds to the year property of a score, so I assumed the map's keys are the years and not the scores as you suggested.
I didn't check if the code works, but it should at least give you an idea on how to fill your map.
It looks like you're being tasked with reading data from a file, and then generating some stats about the data in the file.
Currently, you're simply plopping each line in the ArrayList.
Looks like your next step is to go through each item in that list, and create a UniversityScore object. This is where you will have to parse each string into values that can be assigned to the various fields in the UniversityScore object. When you have done that, put the current line number (as an Integer key) and UniversityScore (as the value) in your HashMap.
Once you have done that, you will have to write the missing methods getScoresOfYear(Integer year), getAverageOfYear(int year), getMinOfYear(int year), and getMaxOfYear(int year) in the editor class.
try this:
public void fillHashMap() {
for(String line : lines) {
String [] fields = line.split(";");
UniversityScores us = new UniversityScores(fields[0], fields[1], fields[2], fields[3]);
if (scores.keySet().contains(us.getScore())) {
scores.get(us.getScore()).add(us);
}
else {
ArrayList<UniversityScores> t = new ArrayList<UniversityScores>();
t.add(us);
scores.put(us.getScore(), t);
}
}
}
So in my main class called testPara, whenever I want to execute the methods in my class paragraph, I always have to write the file name inside the parameter of my methods. For example: g.readFile(file), g.countSentence(file). What would I have to do so methods won't require and I could execute just by g.count(). Maybe a global variable? This my paragraph class:
import java.util.*;
import java.util.ArrayList;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
class paragraph {
public void readFile(File filename) {
try {
Scanner scanner = new Scanner(filename);
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
}
public void countSentences(File filename) {
int sentanceCount = 0;
String line;
String delimiters = "?!.";
try {
Scanner scanner = new Scanner(filename);
while(scanner.hasNextLine()) {
line = scanner.nextLine();
for(int i = 0; i < line.length(); i++) {
if (delimiters.indexOf(line.charAt(i)) != -1) {
sentanceCount++;
}
}
}
System.out.println("# of sentances: " + sentanceCount);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
}
This is how I'm testing my methods
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class testPara {
public static void main(String args[]) {
paragraph g = new paragraph();
File file = new File("story.txt");
g.readFile(file);
System.out.println("\n");
g.countSentences(file);
}
}
This makes only sense if your Paragraph class works with the same file the whole time. Then you could just add a field private File file; or something to the Paragraph class and use a setter to set the File object once. Like so:
public class Paragraph {
private File file;
public void setFile(File file){
this.file = file;
}
....
...and in the main method:
Paragraph p = new Paragraph();
p.setFile(new File("whatever.txt"));
p.readFile();
p.countSentences();
....
Of course you'll have to modify your readFile() method (etc) so they use the new "file" class variable.
EDIT: Or, as #4castle suggested, you could use a constructor to hand over the File instance (if your class needs this instance to work properly, this would be the right approach).
Make filename an instance variable of your class Paragraph
class Paragraph {
private String filename;
. . .
// constructor taking the argument for filename
public Paragraph(String filename) {
this.filename = filename;
. . .
and have the caller pass the value in when constructing an object from that class
Paragraph g = new Paragraph("story.txt");
After that, your methods do not need the argument anymore, they
can just take the value from the instance variable. For example
public void countSentences() {
Scanner scanner = new Scanner(this.filename);
Hey I'm making a program that takes words+definitions from a text document, scrambles them, then quizzes you on them. The words are structured as (word: definition). I finished the code for the project but for some reason the console stays blank after I compile. The code consists of three classes that I'll display below:
Class 1 :-
public class VocabularyWord {
private String word, definition;
public VocabularyWord(String w, String d){
word=w;
definition=d;
}
public String getDefinition(){
return definition;
}
public String getWord(){
return word;
}
public String toString(){
return word+" "+definition;
}
}
Class 2 :-
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class VocabularyTest {
private ArrayList<VocabularyWord>words;
private int c;
public VocabularyTest() throws FileNotFoundException{
words=new ArrayList<VocabularyWord>();
ArrayList<String> str=new ArrayList<String>();
File inputFile = new File("Vocabulary.txt");
Scanner input = new Scanner(inputFile);
while(input.hasNextLine()){
str.add(input.nextLine());
processStrings(str);
for(int i = 0; i<100; i++)
swapWords();
}
}
private void processStrings(ArrayList<String>lines){
int pos=0;
for(int i=lines.size()-1; i>=0; i--){
pos=lines.get(i).indexOf(":");
String s=lines.get(i).substring(0, pos);
String ss=lines.get(i).substring(pos+1, lines.get(i).length());
VocabularyWord p=new VocabularyWord(s,ss);
words.add(p);
c++;
}
}
private void swapWords(){
int x=(int) (Math.random()*words.size());
int xx=(int)(Math.random()*words.size());
while(x==xx)
xx=(int)(Math.random()*words.size());
Collections.swap(words, xx, x);
}
public void quiz(){
System.out.println("hi");
int n=0;
Scanner kb=new Scanner(System.in);
for(int i=words.size()-1; i>=0; i--){
System.out.println(words.get(i).getDefinition());
if(kb.nextLine().equals(words.get(i).getWord())){
System.out.println("Nice Job!");
n++;
}
else
System.out.println(words.get(i).getWord());
}
System.out.println("You got "+n+" correct!");
}
}
Class 3 :-
import java.io.FileNotFoundException;
public class VocabTestTester {
public static void main(String[] args)throws FileNotFoundException{
VocabularyTest test= new VocabularyTest();
test.quiz();
}
}
I'm guessing that your VocabularyTest constructor is failing, possibly that you're not finding the file adequately, although I'd expect to see an exception from this. You'd do well to check this.
Print "hi" on the first line of the VocabularyTest constructor, print out the file path, and check that it matches the path that you expect, and then print out the words read in to the console.
e.g.,
public VocabularyTest() throws FileNotFoundException{
System.out.println("In VocabularTest Constructor");
words=new ArrayList<VocabularyWord>();
ArrayList<String> str=new ArrayList<String>();
File inputFile = new File("Vocabulary.txt");
System.out.println(inputFile.getAbsolutePath());
Scanner input = new Scanner(inputFile);
while(input.hasNextLine()){
System.out.println(input.nextLin());
}
In a part of my university project I have to get a text with some lines then saving it in a string or a string array.My problem is that in scanner class using methods gets only one line of the input. So I cannot get the other lines.please help me.
public class Main {
public static void main(String[] args) {
java.util.Scanner a = new java.util.Scanner(System.in);
String b = "";
while (a.hasNextLine()) {
b += a.nextLine();
}
}
}
You can try to use isEmpty to detect an enter-only input.
UPDATED:
If your input also contain a blank line, then you may specify another terminator character(s); instead of only an empty string.
public class Main {
public static void main(String[] args) {
//for example ",,"; then the scanner will stop when you input ",,"
String TERMINATOR_STRING = ",,"
java.util.Scanner a = new java.util.Scanner(System.in);
StringBuilder b = new StringBuilder();
String strLine;
while (!(strLine = a.nextLine()).equals(TERMINATOR_STRING)) {
b.append(strLine);
}
}
}
If you are building your program from command line, then there's something called "input redirection" which you can use. Here's how it works:
Let's suppose your program is:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ScanningMultiline
{
public static void main (String[] args)
{
List<String> lines = new ArrayList<> ();
try (Scanner scanner = new Scanner (System.in))
{
while (scanner.hasNextLine ())
{
lines.add (scanner.nextLine ());
}
}
System.out.println ("Total lines: " + lines.size ());
}
}
Now suppose you have input for your program prepared in a file.
To compile the program you'd change the current directory of terminal/command prompt to the program directory and then write:
javac ScanningMultiline.java
And then to run, use input redirection like:
java ScanningMultiline < InputFile.txt
If your InputFile.txt is in another directory, just put its complete path instead like:
java ScanningMultiline < "/Users/Xyz/Desktop/InputFile.txt"
Another Approach
You can try reading your input directly from a file. Here's how that program would be written:
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ScanningMultiline
{
public static void main (String[] args)
{
final String inputFile = "/Users/Xyz/Desktop/InputFile.txt";
List<String> lines = new ArrayList<> ();
try (Scanner scanner = new Scanner (Paths.get (inputFile)))
{
while (scanner.hasNextLine ())
{
lines.add (scanner.nextLine ());
}
}
catch (IOException e)
{
e.printStackTrace ();
}
System.out.println ("Total lines: " + lines.size ());
}
}
This approach reads directly from a file and puts the lines from the file in a list of String.
Another Approach
You can read the lines from a file and store them in a list in a single line as well, as the following snippet demonstrates:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class ScanningMultiline
{
public static void main (String[] args) throws IOException
{
final String inputFile = "/Users/Xyz/Desktop/InputFile.txt";
List<String> lines = Files.readAllLines (Paths.get (inputFile));
}
}
Yohanes Khosiawan has answered a different approach so I'm not writing that one here.