In the following code I read text file with a list of movies and create a String array of the list of movies using a helper method. Within the method I am able to read and print each line of the file. However, when I attempt to iterate over the returned array in the main method I get only "null". Why is this happening. In my research so far, I have not been able to find a similar problem posted by someone else. Please help. Thanks.
import java.util.Random;
import java.util.Scanner;
import java.io.File;
public class GuessTheMovie {
public static void main(String[] args) throws Exception {
try {
// Create File and Scanner objects
File file = new File("movies.txt");
Scanner scanner = new Scanner(file);
// Create String array to store all movie titles
List<String> movies = createMoviesArray(scanner);
for (String movie : movies) {
System.out.println(movie);
}
/*
String[] movies = createMoviesArray(scanner);
for (int i = 0; i < movies.length; i++) {
System.out.println(movies[i]);
} */
} catch (Exception e) {
System.out.println("Could not find file.");
}
}
////////////////////////// HELPER METHODS ////////////////////////////////////
/*
// Create String array to store all movie titles
private static String[] createMoviesArray(Scanner scanner) {
int count = 0;
String[] movies; // = new String[500];
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(count + " : " + line);
count += 1;
}
movies = new String[count];
return movies;
}*/
private static List<String> createMoviesArray(Scanner scanner) {
List<String> movies = new ArrayList<>();
// get line count for the size of the array
while (scanner.hasNextLine()) {
movies.add(scanner.nextLine());
}
return movies;
}
That is quite normal, since you don't put any values in your array.
private static String[] createMoviesArray(Scanner scanner) {
int count = 0;
String[] movies; // = new String[500];
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(count + " : " + line);
count += 1;
}
movies = new String[count]; // all you do here, is create an array with 'count' spaces, all default values (being null)
return movies;
}
If you want to work like this, you have two options (that immediately jump to mind):
Use an array, and create a new one for after every read. This is very resource consuming, meaning: DON'T DO THIS
Since you don't know the number of elements before all are read: use a List.
private static List<String> createMoviesArray(Scanner scanner) {
List<String> movies = new ArrayList<>();
while (scanner.hasNextLine()) {
movies.add(scanner.nextLine());
}
return movies;
}
Just before return in the createMoviesArray() method you create a new array. You never add anything to that array and thus it is empty after returning from that method. You should make a new array before iterating over the file.
If you don't know the size of the file and how many lines it has you probably should use some Collection with dynamic size, like ArrayList.
With your line movies = new String[count]; you are creating a new array of Strings. At this point in time the array will contain only NULL values which. Nowhere in your code you are actually writing something into the array. Thats why your main method correctly prints null.
This is because you are not adding the data to the movies array, you are only initializing it.
If you were to print the movies object at the end of your helper method you would see that it also is null.
I suggest using an ArrayList as you don't know how large the array needs to be, it would then go something like this:
import java.util.Random;
import java.util.Scanner;
import java.io.File;
public class GuessTheMovie {
public static void main(String[] args) throws Exception {
try {
// Create File and Scanner objects
File file = new File("movies.txt");
Scanner scanner = new Scanner(file);
// Create String array to store all movie titles
ArrayList<String> movies = createMoviesArray(scanner); // change this to ArrayList
for (movie : movies) { // I used a foreach loop
System.out.println(movie);
}
} catch (Exception e) {
System.out.println("Could not find file.");
}
}
////////////////////////// HELPER METHODS ////////////////////////////////////
// Create String array to store all movie titles
private static String[] createMoviesArray(Scanner scanner) {
int count = 0;
ArrayList<String> movies = new ArrayList<String>(); // change to Array List
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(count + " : " + line);
count += 1;
movies.add(line); // Add to end of ArrayList
}
return movies;
}
You can do the same thing in this way also:-
package com.adddemo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class GuessTheMovie {
public static void main(String[] args) throws Exception {
try {
// Create File and Scanner objects
File file = new File("C:\\Users\\lenovo\\Desktop\\movies.txt");
Scanner scanner = new Scanner(file);
// Create String array to store all movie titles
List movies = createMoviesArray(scanner);
for (int i = 0; i < movies.size(); i++) {
System.out.println(i+" : "+movies.get(i));
}
} catch (Exception e) {
System.out.println("Could not find file.");
}
}
////////////////////////// HELPER METHODS ////////////////////////////////////
// Create String array to store all movie titles
private static List createMoviesArray(Scanner scanner) {
int count = 0;
List movies = new ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(count + " : " + line);
count += 1;
movies.add(line);
}
return movies;
}
}
Related
I'm trying to search of multiple words given from a user ( i used array to store them in ) from one txt file , and then if that word presented once in the file it will be displayed and if it's not it won't.
also for the words itself , if it's duplicated it will search it once.
the problem now when i search for only one it worked , but with multiple words it keeps repeated that the word isn't present even if it's there.
i would like to know where should i put the for loop and what's the possible changes.
package search;
import java.io.*;
import java.util.Scanner;
public class Read {
public static void main(String[] args) throws IOException
{
Scanner sc = new Scanner(System.in);
String[] words=null;
FileReader fr = new FileReader("java.txt");
BufferedReader br = new BufferedReader(fr);
String s;
System.out.println("Enter the number of words:");
Integer n = sc.nextInt();
String wordsArray[] = new String[n];
System.out.println("Enter words:");
for(int i=0; i<n; i++)
{
wordsArray[i]=sc.next();
}
for (int i = 0; i <n; i++) {
int count=0; //Intialize the word to zero
while((s=br.readLine())!=null) //Reading Content from the file
{
{
words=s.split(" "); //Split the word using space
for (String word : words)
{
if (word.equals(wordsArray[i])) //Search for the given word
{
count++; //If Present increase the count by one
}
}
if(count == 1)
{
System.out.println(wordsArray[i] + " is unique in file ");
}
else if (count == 0)
{
System.out.println("The given word is not present in the file");
}
else
{
System.out.println("The given word is present in the file more than 1 time");
}
}
}
}
fr.close();
}
}
The code which you wrote is error prone and remember always there should be proper break condition when you use while loop.
Try the following code:
public class Read {
public static void main(String[] args)
{
// Declaring the String
String paragraph = "These words can be searched";
// Declaring a HashMap of <String, Integer>
Map<String, Integer> hashMap = new HashMap<>();
// Splitting the words of string
// and storing them in the array.
String[] words = new String[]{"These", "can", "searched"};
for (String word : words) {
// Asking whether the HashMap contains the
// key or not. Will return null if not.
Integer integer = hashMap.get(word);
if (integer == null)
// Storing the word as key and its
// occurrence as value in the HashMap.
hashMap.put(word, 1);
else {
// Incrementing the value if the word
// is already present in the HashMap.
hashMap.put(word, integer + 1);
}
}
System.out.println(hashMap);
}
}
I've tried by hard coding the values, you can take words and paragraph from the file and console.
The 'proper' class to use for extracting words from text is java.text.BreakIterator
You can try the following (reading line-wise in case of large files)
import java.text.BreakIterator;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class WordFinder {
public static void main(String[] args) {
try {
if (args.length < 2) {
WordFinder.usage();
System.exit(1);
}
ArrayList<String> argv = new ArrayList<>(Arrays.asList(args));
String path = argv.remove(0);
List<String> found = WordFinder.findWords(Files.lines(Paths.get(path)), argv);
System.out.printf("Found the following word(s) in file at %s%n", path);
System.out.println(found);
} catch (Throwable t) {
t.printStackTrace();
}
}
public static List<String> findWords(Stream<String> lines, ArrayList<String> searchWords) {
List<String> result = new ArrayList<>();
BreakIterator boundary = BreakIterator.getWordInstance();
lines.forEach(line -> {
boundary.setText(line);
int start = boundary.first();
for (int end = boundary.next(); end != BreakIterator.DONE; start = end, end = boundary.next()) {
String candidate = line.substring(start, end);
if (searchWords.contains(candidate)) {
result.add(candidate);
searchWords.remove(candidate);
}
}
});
return result;
}
private static void usage() {
System.err.println("Usage: java WordFinder <Path to input file> <Word 1> [<Word 2> <Word 3>...]");
}
}
Sample run:
goose#t410:/tmp$ echo 'the quick brown fox jumps over the lazy dog' >quick.txt
goose#t410:/tmp$ java WordFinder quick.txt dog goose the did quick over
Found the following word(s) in file at quick.txt
[the, quick, over, dog]
goose#t410:/tmp$
I currently have the words reading from a text file into a String ArrayList. My assignment asked me to not use any HashMaps or HashSets, anything of that nature. While counting the occurrences of a word I also have to remove any additionals(, . : [] ; = -) and duplicates of the same word. Just currently having trouble with how to remove the additionals and removing duplicates any help is appreciated (Beginner at Java). Unable to use splits.
Here is my code:
public static void main(String[] args) throws FileNotFoundException, IOException
{
//Create input Scanner
FileInputStream file = new FileInputStream("Assignment1BData.txt");
Scanner input = new Scanner(file);
//Create the ArrayList
ArrayList<String> wordCount = new ArrayList<String>();
ArrayList<Integer> numCount = new ArrayList<Integer>();
//Read through the file and find the words from text
while(input.hasNext())
{
String word = input.next();
//Create index to look through lines of text
if(wordCount.contains(word))
{
int index = numCount.indexOf(word);
numCount.set(index, numCount.get(index) + 1);
}
else
{
wordCount.add(word);
numCount.add(1);
}
}
input.close();
file.close();
//Print output in for loop
for(int i = 0; i < wordCount.size(); i++)
{
System.out.println(wordCount.get(i) + " = " + numCount.get(i));
}
}
indexOf(Object o) method on the ArrayList should solve the problem of duplicates. Before you go on to add the string to the ArrayList simply call this method if that string already exists in the ArrayList it returns the index otherwise it returns -1. Just keep adding the string read from the text file to ArrayList as long as the indexOf method returns -1 otherwise simply ignore(since it already exists).
You can use something like: newList = removeDuplicates(YourList) So that the duplicates would get removed and you get a new list...
Got it here: https://www.geeksforgeeks.org/how-to-remove-duplicates-from-arraylist-in-java/
You can try by creating a list with unique elements using Stream API as,
List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0);
List<Integer> listWithoutDuplicates = listWithDuplicates.stream()
.distinct()
.collect(Collectors.toList());
Then iterate over the original array/list (listWithDuplicates ) and get it compared with listWithoutDuplicates and count for the match.
Try this, for replacng special symbols before doing lookup and doing the count .
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class WordCounter {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//Create input Scanner
FileInputStream file = new FileInputStream("/tmp/Assignment1BData.txt");
Scanner input = new Scanner(file);
//Create the ArrayList
ArrayList<String> wordCount = new ArrayList<String>();
ArrayList<Integer> numCount = new ArrayList<Integer>();
//Read through the file and find the words from text
while(input.hasNextLine())
{
String word = input.nextLine();
//Replace all characters
word = word.replaceAll("[,.:;=-\\[\\]]", "");
//Create index to look through lines of text
if(wordCount.contains(word))
{
int index = wordCount.indexOf(word);
numCount.set(index, numCount.get(index) + 1);
}
else
{
wordCount.add(word);
numCount.add(1);
}
}
input.close();
file.close();
//Print output in for loop
for(int i = 0; i < wordCount.size(); i++)
{
System.out.println(wordCount.get(i) + " = " + numCount.get(i));
}
}
}
at the beginning I read the file and used split() method and stored each value in 1d array. i must store index 0 and 1 in a string value ans index 2,3 and 4 must be stored in 1d array because "supervisor" object arguments contains two string values(name and id) and 1d array (interests) the problem is at row 0 there is an extra interest (3 interests) and at row 1 and 2 there are two interests.
what i thought about is to store the interests in an arraylist (because the size is not static )and convert it back to 1d array but it did not work
tries to store the interests in 2d array and convert t back to 1d array but it did not work , while splitting the file i splitted (, and #) but i noticed at the end of every interest there is a #
so i kept the # and thought if i can do an if condition while reading the file. is there any simple idea to avoid the error?
the file supervisor.txt contains:
00023, Dr. Haneen, artificial intelligent, data mining, pattern recognition#
00013, Dr. Manar, database, network#
00011, Dr. Hajar, software engineering, games#
Code
public static void main(String[] args)throws Exception {
File supervisorFile=new File("supervisor.txt");
if (!supervisorFile.exists()) {
System.out.println("Sorry the file is not found!"); //checks if the file exists if no it terminates the program
System.exit(0);
}
supervisor sup=null;
String[]supArray=null;
Scanner supRead=new Scanner(supervisorFile);//read supervisor file
while (supRead.hasNext()) {
supArray=supRead.nextLine().split(",");
sup=addSupervisor(supArray);
//System.out.println(sup.toString());
}
}
public static supervisor addSupervisor(String[]arr){
String id=arr[0];
String name=arr[1];
String[] interest=new String[3];
for (int i = 0; i < interest.length; i++) { //here i tried to store all the interests
interest[i]=arr[2]+arr[3]+arr[4];
}//it prints artificial intelligent data mining pattern recognition# and then an indexOutOfBoundsException
return new supervisor(id,name,interest);
}
The solution is to use split with a limit parameter.
class Supervisor{
final String id;
final String name;
String[] fields;
Supervisor(String id, String name, String[] fields) {
this.id = id;
this.name = name;
this.fields = fields;
}
}
Path path = Paths.get("supervisor.txt");
List<Supervisor> supervisors = Files.lines(path, Charset.defaultCharset())
.filter(l -> l.endsWith("#"))
.map(l -> l.substring(0, l.length() - 1)) // Remove #
.map(l -> l.split(",\\s*", 3)) // "00013", "Dr. Manar", "database, network"
.filter(w -> w.length == 3)
.map(w -> new Supervisor(w[0], w[1], w[2].split(",\s*")))
.collect(Collectors.toList());
Use split & ArraysList
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.AllArgsConstructor;
#AllArgsConstructor
class Supervisor {
String id;
String name;
List<String> interest;
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);
}
}
public class AMain {
public static void main(String[] args) {
String id, name, line;
String[] arr;
List<String> list = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("file/supervisor.txt"))) {
while ((line = br.readLine()) != null) {
arr = line.trim().split(",");
list.addAll(Arrays.asList(arr));
if (list.size() > 2) {
id = list.get(0); // get id
list.remove(0); // remove id
name = list.get(0); // get name
list.remove(0); // remove name
System.out.println(new Supervisor(id, name, list));
}
list.clear(); // clear all
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
[id=00023,name= Dr. Haneen,interest=[ artificial intelligent, data mining, pattern recognition#]]
[id=00013,name= Dr. Manar,interest=[ database, network#]]
[id=00011,name= Dr. Hajar,interest=[ software engineering, games#]]
Your second and third line only has 4 Strings split up by a comma. That makes it 4 Strings in the Array. In your addSupervisor methode you are trying to access arr[4], the 5th String, which is out of bound.
You get an error because you are trying to use arr[4], but wioth the lines 2 and 3 the size of the array will be 4, so the maximum index you can use is 3.
I don't know for sue what Supervisor is, but would this work:
public static supervisoraddSupervisor(String[]arr){
String id=arr[0];
String name=arr[1];
String[] interest=new String[arr.length - 2];
for (int i = 0; i < interest.length; i++) {
interest[i]=arr[i + 2];
}
return new supervisor(id,name,interest);
}
Try it online!
First you should get the line and then work with it like you do. The problem is in the loop for where you suppose all the "supervisor" have 3 interests. Also you are storing all the interest in the first pos of the array:
for (int i = 0; i < interest.length; i++) { //here i tried to store all the interests
interest[i]=arr[2]+arr[3]+arr[4];
}
So I think you should use a function like this:
private static String[] extractInterest(String[] line) {
String[] res = new String[line.length - 2]; //There are two index that haven't got interest
for(int i = 0; i<res.length; ++i) {
res[i] = line[i+2].replaceFirst(" ", "").replace("#","");
}
return res;
}
And this is the "main":
public static void main(String[] args) {
File file = new File("Data.txt");
try (Scanner sc = new Scanner(file)) { //Will close the sc automatically
String[] line;
while(sc.hasNext()) {
line = sc.nextLine().split(",");
int id = Integer.parseInt(line[0]);
String name = line[1].replaceFirst(" ",""); //For delete first " "
String[] interest = extractInterest(line);
Supervisor s = new Supervisor(id,name,interest);
System.out.println(s.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
A final advice, Java classes names must begin with uppercase by agreement. So you should change the name of your class "supervisor" to "Supervisor"
I'm trying to make a method in java that will use a scanner to read a List String. I want the program to divide the array word by word using the delineator "//s". I already got each array by the names of the people in the text file, I am just trying to divide the array further so that way i can sort them by there information (Ex. if they have f for female I would be able to call that specific part of the array using arrayList.get(index) and sort it by gender that way) Here is my code:
Sorry for being unclear, here is my full code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class Filereader {
public static void replaceSlash(List<String> array) {
for (int i = 0; i < array.size(); i++)
{
if (array.get(i).contains("-"))
{
array.set(i, array.get(i).replace("-", "/"));
}
}
}
public static void split( List<String> array ) {
Scanner scanner = new Scanner().useDelimiter("\\s");
for (int i= 0; i < array.size(); i++) {
while (scanner.hasNext()) {
array.set(i, scanner.next());
}
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println("Please type the name of the file you wish to sort: ");
//get the name of the file
Scanner scanner = new Scanner(System.in);
File fileName = new File(scanner.nextLine());
scanner = new Scanner(fileName).useDelimiter("\\s");
List<String> annaK = new ArrayList<String>();
List<String> martinaH = new ArrayList<String>();
List<String> monicaS = new ArrayList<String>();
while (scanner.hasNextLine()) {
annaK.add(scanner.nextLine());
martinaH.add(scanner.nextLine());
monicaS.add(scanner.nextLine());
}
replaceSlash(annaK);
replaceSlash(martinaH);
replaceSlash(monicaS);
split(annaK);
System.out.println(annaK);
System.out.println(martinaH);
System.out.println(monicaS);
}
}
You can make one scanner for every string within the list, then loop over that
for (String a : array) {
Scanner scanner = new Scanner(a).useDelimiter("\\s");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
}
However, a.split() or StringTokenizer make more sense than a Scanner here
Besides that, array.set won't work because you're assigning the same i value for multiple words within each individual a value... Which will result in only the last value in the scanned string to be assigned to that index of the list
If you're trying to splits all words within a list into a new list, then you'll actually need to create and append values to a separate list object (don't modify your parameters, and don't have methods with side effects)
I'm trying to calculate how many words an ArrayList contains. I know how to do this if every words is on a separate line, but some of the words are on the same line, like:
hello there
blah
cats dogs
So I'm thinking I should go through every entry and somehow find out how many words the current entry contains, something like:
public int numberOfWords(){
for(int i = 0; i < arraylist.size(); i++) {
int words = 0;
words = words + (number of words on current line);
//words should eventually equal to 5
}
return words;
}
Am I thinking right?
You should declare and instantiate int words outside of the loop the int is not reassign during every iteration of the loop. You can use the for..each syntax to loop through the list, which will eliminate the need to get() items out of the list. To handle multiple words on a line split the String into an Array and count the items in the Array.
public int numberOfWords(){
int words = 0;
for(String s:arraylist) {
words += s.split(" ").length;
}
return words;
}
Full Test
public class StackTest {
public static void main(String[] args) {
List<String> arraylist = new ArrayList<String>();
arraylist.add("hello there");
arraylist.add("blah");
arraylist.add(" cats dogs");
arraylist.add(" ");
arraylist.add(" ");
arraylist.add(" ");
int words = 0;
for(String s:arraylist) {
s = s.trim().replaceAll(" +", " "); //clean up the String
if(!s.isEmpty()){ //do not count empty strings
words += s.split(" ").length;
}
}
System.out.println(words);
}
}
Should looks like this:
public int numberOfWords(){
int words = 0;
for(int i = 0; i < arraylist.size(); i++) {
words = words + (number of words on current line);
//words should eventually equal to 5
}
return words;
}
I think this could help you .
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
public class LineWord {
public static void main(String args[]) {
try {
File f = new File("C:\\Users\\MissingNumber\\Documents\\NetBeansProjects\\Puzzlecode\\src\\com\\test\\test.txt"); // Creating the File passing path to the constructor..!!
BufferedReader br = new BufferedReader(new FileReader(f)); //
String strLine = " ";
String filedata = "";
while ((strLine = br.readLine()) != null) {
filedata += strLine + " ";
}
StringTokenizer stk = new StringTokenizer(filedata);
List <String> token = new ArrayList <String>();
while (stk.hasMoreTokens()) {
token.add(stk.nextToken());
}
//Collections.sort(token);
System.out.println(token.size());
br.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
}
So you'll red data from a file in this case and store them in a list after tokenizing them , just count them , If you just want to get input from the console use the Bufferedreader , tokenize them , separating with space , put in list , simple get size .
Hope you got what you are looking for .