I have a text file with about 5000 names or so, each separated by line.
I am have already accomplished adding all the names to an ArrayList "names", but
i am not able to add anything to my arrayList scores.
I don't know where I'm going wrong, especially in the addScores method, nothing gets outputted at all.
If anymore information is required, please ask.
And thanks for the help..
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class ScoringNames {
BufferedReader x = null;
String location = "xxxxx\\names.txt";
ArrayList<String> names = new ArrayList<String>();
ArrayList<Integer> scores = new ArrayList<Integer>();
public void readFile(){ //Opens file, and prints every line.
try{
x = new BufferedReader(new FileReader(location));
} catch(FileNotFoundException e) {
e.printStackTrace();
}
try{
String name = x.readLine();
while(name != null){
//System.out.println(name);
names.add(name);
name = x.readLine();
}
} catch(IOException e) {
e.printStackTrace();
}
}
public int nameScore(String name){
this.readFile(); //Open file and read, so that values are added to <names>
this.sortNames();
int score = 0;
char[] tempName = name.toCharArray();
for (char i : tempName){
score += alphValue(i);
}
return score;
}
public void addScores(){
for(String x : names){
scores.add(nameScore(x));
}
}
public void printScores(){
for(int counter: scores)
System.out.println(counter);
}
public static void main(String[] args) {
ScoringNames abc = new ScoringNames();
abc.readFile();
abc.addScores();
abc.printScores();
}
}
The error i get is:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at ScoringNames.addScores(ScoringNames.java:148)
at ScoringNames.main(ScoringNames.java:163)
You are modifying the List names while accessing it from the For loop of addScores() method.
When you call nameScore(String str) method, Then you don't need to read the file again as all data has been read already and stored in the names list. You need to do just evaluation of the String and return the score.
public int nameScore(String name){
int score = 0;
char[] tempName = name.toCharArray();
for (char i : tempName){
score += alphValue(i);
}
return score;
}
Change method nameScore - remove two top lines.
this.readFile(); // Open file and read, so that values are added to
// <names>
this.sortNames();
There are not unnecessary and the readFile() is the reason of the error.
The reason of the error is that you try to change this.names value in for each loop (for (String x : names)) and that is forbidden in Java.
public int nameScore(String name) {
int score = 0;
char[] tempName = name.toCharArray();
for (char i : tempName) {
score += alphValue(i);
}
return score;
}
Related
I have a Java program that reads elements from a file, stores them in a 2d array and then it manipulates them according by commiting several operations.
I have already implemented the program by using a 2d array and now I want to find a way to turn this array into a 2d ArrayList, so I can manipulate these elements individually, like i did with the 2d array.
The program reads from a file that looks like this:
Jason,56
Martha,89
James,23
...
Here is my code attempting to convert my 2d array into a 2d ArrayList:
Keep in mind that I want all the names to be stored in the 1st column of the array/ArrayList and the age in the second column:
public class Testr {
public static void main(String[] args) throws FileNotFoundException, IOException {
Scanner sc = new Scanner(new BufferedReader(new FileReader("C:\\Users\\test.csv")));
int num_rows = countLines("C:\\Users\\test.csv");
System.out.println("Num of rows : " + num_rows);
int num_cols = countColumns("C:\\Users\\test.csv");
System.out.println("Num of cols : " + num_cols);
String[][] Entries_arr = new String[num_rows][num_cols];
while(sc.hasNextLine())
{
for(int i = 0; i < Entries_arr.length; i++)
{
String[] line;
line = sc.nextLine().trim().split(";");
for(int j = 0; j < line.length; j++)
{
Entries_arr[i][j] = line[j];
}
}
}
List<List<String>> Entries = new ArrayList<List<String>>();
for(int i = 0; i < Entries_arr.length; i++)
{
List<String> recs = new ArrayList<String>();
for(int j = 0; j < Entries_arr[i].length; j++)
{
recs.add(String.valueOf(Entries_arr[i][j]));
}
Entries.add(recs);
}
System.out.println(Entries);
}
//------------------------------------------------------------------------------------------------------------------------
public static int countLines(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count;
} finally {
is.close();
}
}
//------------------------------------------------------------------------------------------------------
public static int countColumns(String filename) {
File file = new File(filename);
Scanner scanner;
try {
scanner = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return -1;
}
int number = 0;
if (scanner.hasNextLine()) {
number = scanner.nextLine().split(";").length;
}
scanner.close();
return number;
}
}
Any help is appreciated.
Going back to what was pointed out in the comments
Don't use a 2D array (or a 2D list) because you'd be using something similar to parallel arrays or parallel lists as your data structure. See Jon Skeet's Anti-Pattern: Parallel Collections blog for details.
Also by trying to solve your problem with a 2D array/list your code gets much more complicated than actually necessary (and for no good reason).
So how could an approach look like as pointed out in the comments?
Following code
reads a test file line by line,
processes each line into a User instance,
and collects them all into an ArrayList.
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FileToList {
public static void main(String[] args) {
try (Stream<String> lines = Files.lines(findCsvFile())) {
List<User> users = lines
.map(FileToList::process)
.flatMap(Optional::stream)
.collect(Collectors.toCollection(ArrayList::new));
System.out.println(users);
} catch (Exception e) {
System.out.println("Error when accessing the file\n");
e.printStackTrace();
}
}
static Path findCsvFile() throws Exception {
URL resource = FileToList.class.getResource(FileToList.class.getSimpleName() + ".class");
return Paths.get(resource.toURI()).resolveSibling("test.csv");
}
static Optional<User> process(String line) {
Optional<User> user = Optional.empty();
String[] values = line.split(",");
try {
String name = values[0];
int age = Integer.parseInt(values[1]);
User actualUser = new User(name, age);
user = Optional.of(actualUser);
} catch (Exception e) {
System.out.printf("Cannot process line: \"%s\" | Error: %s\n", line, e);
}
return user;
}
static class User {
private final String userFirstName;
private final int userAge;
User(String name, int age) {
this.userAge = age;
this.userFirstName = name;
}
public String getUserFirstName() {
return userFirstName;
}
public int getUserAge() {
return userAge;
}
#Override
public String toString() {
return String.format("%s(%d)", userFirstName, userAge);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return userAge == user.userAge &&
Objects.equals(userFirstName, user.userFirstName);
}
#Override
public int hashCode() {
return Objects.hash(userFirstName, userAge);
}
}
}
Running the above code against your example CVS file then outputs
[Jason(56), Martha(89), James(23)]
Note that Optional is used in the process method only to cover for the situation when a line from the CSV file cannot be processed into a new User object. The .flatMap(Optional::stream) then removes any potential optional (non-existing) user instances from the stream before collecting the actual users into an ArrayList.
I'm trying to create a method which will search through an ArrayList containing several words searching for a specific String. Where if the String is not equal to any words in the ArrayList it will add the word to the list, and if the word already exists in the list, it will count how many times the word occurs and then add one more, which will represent the last String input.
This is what I've got so far in my code:
public void leggTilOrd(String ord) {
if (Ord.contains(ord)) {
teller++;
}
if (!Ord.contains(ord)) {
Ord.add(ord);
}
System.out.println(teller);
}
Obviously this will only add one more number in the counter (teller), so what I'm trying to achieve it to add 1 on top of all the occurrences of that specific String in the list and this is where I'm stuck.
Edit: I should also mention that Ord is an ArrayList I've created earlier in the code.
Here's the full code:
import java.util.Scanner;
import java.io.File;
import java.util.ArrayList;
public class Ordliste {
private ArrayList<String> Ord = new ArrayList<String>();
private int teller = 0;
public void lesBok (String filnavn) throws Exception{
Scanner fil = new Scanner(new File(filnavn));
while(fil.hasNextLine()){
Ord.add(fil.next());
} fil.close();
}
public void leggTilOrd(String ord){
if(Ord.contains(ord)){
teller++;
} if (!Ord.contains(ord)){
Ord.add(ord);
} System.out.println(teller);
}
}
Instead of doing this , you can keep track of the strings in your list using a Set
Set<String> set = new HashSet<String>();
public void leggTilOrd(String ord) {
if (set.contains(ord) != null) {
teller++;
} else {
Ord.add(ord);
set.add(ord);
}
System.out.println(teller);
}
Are you tied to using an ArrayList? I'd recommend using a Map<String, Integer> instead and store the number of occurrences of a specific string as value in the map:
if (map.get(ord) != null) {
map.put(ord, map.get(ord) + 1);
}
else {
map.put(ord, 1);
}
Still not sure exactly what you are trying to accomplish, do you increment teller each time you add a different word?
This is a simple way to do what I believe you are attempting, and should get you going in the right direction.
import java.util.Arrays;
import java.util.List;
public class test
{
static int teller = 0;
static List<String> words = Arrays.asList("dog", "cat", "dog");
public static void main(String[] args)
{
System.out.println(teller);
addAndCount("dog");
System.out.println(teller);
teller = 0;
addAndCount("cat");
System.out.println(teller);
teller = 0;
addAndCount("fish");
System.out.println(teller);
}
public static void addAndCount(String newWord)
{
teller += 1 + Math.toIntExact(
words.stream().filter(string -> newWord.equals(string)).count());
words.add(newWord);
}
}
I'm trying to bubble sort car make and year, where I would have the car year sorted and if two car makes are in the same year, then they are sorted alphabetically. My program works up to the point where I call BubbleSorted(). It's giving me an error java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 and I don't know why. My program seems to be correct. Below is my program. I have 3 classes(main, bubblesortCars, GetCarInfo).
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.FileReader;
public class TheMain {
public static void main(String[] args) {
Scanner keyboard=new Scanner(System.in);
int choice;
boolean done = false;
try{
String filename1 = "Demo.txt";
FileReader inputFile = new FileReader(filename1);
//Instantiate the BufferedReader Class
BufferedReader bufferReader = new BufferedReader(inputFile);
ArrayList<GetCarInfo> CarList = new ArrayList();
//Variable to hold the one line data
String line;
StringTokenizer st;
int i=0;
// Read file line by line and print on the console
while ((line = bufferReader.readLine()) != null) {
st = new StringTokenizer(line, "\t");
st.nextToken();
st.nextToken();
String getMake = st.nextToken();
st.nextToken();
int getYear = Integer.parseInt(st.nextToken());
GetCarInfo temp;
temp = new GetCarInfo(getMake, getYear);
CarList.add(temp);
}
bufferReader.close();
BubbleSortCars Sorted = new BubbleSortCars();
Sorted.bubblesorted(CarList, 0, CarList.size());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
import java.util.ArrayList;
public class BubbleSortCars {
ArrayList <GetCarInfo> temp= new ArrayList();
public void bubblesorted(ArrayList <GetCarInfo> grabber, int began, int end){
for(int i =0; i<end-began-1; i++){
for(int j=began; j<(end-i-1); j++){
if(grabber.get(j).year > grabber.get(j+1).year){
temp.set(j, grabber.get(j));
grabber.set(j,grabber.get(j+1));
grabber.set(j+1, temp.get(j));
System.out.println("Success");
}
else if(grabber.get(j).year==grabber.get(j+1).year){
if((grabber.get(j).make).compareTo(grabber.get(j+1).make)>0){
temp.set(j, grabber.get(j));
grabber.set(j, grabber.get(j+1));
grabber.set(j+1, temp.get(j));
System.out.println("Success");
}
}
}
}
}
}
public class GetCarInfo {
int year;
String make;
public GetCarInfo(String newmake, int newyear){
make = newmake;
year = newyear;
}
}
Reason you get IndeOutOfBoundException is due to this line:
temp.set(j, grabber.get(j));
and your definition of arrayList.
ArrayList<GetCarInfo> temp = new ArrayList();
Here you are defining temp as arrayList without any element and you are trying to set an element at 0th location which is not defined. See this for your reference http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#set%28int,%20E%29
When you define temp as above it created with size 0 and jdk does check internally if index that you are trying to access is less than size then only it will allow you to access/set content.
So one way to avoid this, you define your temp arrayList in your method like:
ArrayList<GetCarInfo> temp = new ArrayList(grabber);
Or you could use grabber arrayList to do the sorting without any other data structure.
The problem is with the ArrayList temp. Please refer the Oracle documentation for the set method.
Here you don't need an ArrayList. User a simple GetCarInfo object as temp variable.
the repeated items in the text file should not be added to the list but this program is outputing every word from the list dont know why hasElement method is not working.I need to create an program object which should be called MTFencoder.java and it should accept the name of a text file as a command-line argument such that if there exists a text file called story.txt then your program could be invoked with the following command:
java MTFencoder test.txt
It should produce one line of output for each word of the input file, such that when a word is first encountered then the output is:
0 word
and if the word has been encountered before then the output is a single integer specifying the index of that word in a list of known words ordered according to the most recently used (MRU order).
import java.util.*;
import java.io.*;
class extmycase
{
public static void main(String [] args)
{
Scanner scan=null;
Scanner scan1=null;
wordlist word=null;
String s;
int count=0;
try
{
scan=new Scanner(new File(args[0]));
scan1=new Scanner(new File(args[0]));
while(scan1.hasNext())
{
scan1.next();
count++;
}
System.out.println("No.of words : " + count);
word = new wordlist(count);
while(scan.hasNext())
{
s=scan.next();
if(word.hasElement(s)==true)
{
System.out.println("has element");
}
else
{
word.add(s);
}
}
word.showlist();
}
catch(Exception e)
{
System.err.println("unable to read from file");
}
finally
{
// Close the stream
if(scan != null)
{
scan.close( );
}
if(scan1 !=null)
{
scan1.close();
}
}
}
}
the wordlist program is
import java.lang.*;
import java.util.*;
public class wordlist
{
public String data [];
private int count;
private int MAX;
public wordlist(int n)
{
MAX = n;
data = new String[MAX];
count = 0;
}
// Adds x to the set if it is not already there
public void add(String x)
{
if (count<MAX)
{
data[count++] = x;
}
}
// Removes x from set by replacing with last item and reducing size
public void replace(String x)
{
for(int i=0;i<count;i++)
{
if(data[i]==x)
{
data[count]=data[i];
for(int j=i;j<count;j++)
data[j]=data[j+1];
}
}
}
// Checks if value x is a member of the set
public boolean hasElement(String x)
{
for(int i=0;i<=count;i++)
{
if(data[i].equals(x))
{
return true;
}
}
return false;
}
public int findIndex(String x)
{
for(int i=0;i<=count;i++)
{
if(data[i].equals(x))
{
return i;
}
}
return 0;
}
public void showlist()
{
int l=0;
for(int i=0;i<count;i++)
{
System.out.println(data[i]);
l++;
}
System.out.println(l);
}
}
Your wordlist will never contain any elements. It is constructed, which sets everything to 0, and then you see whether it contains words, with of course it will never do. Also, both scanners point to the same file, so every word that exists from one will have to exist in the other, and all words will be found making this semi-redundant in the first place.
I am trying to work out how to scan a text file of a conversation find how many positive words and negative words there are. The positive and negative words are contained within two separate text files which are used to 'scan' the conversation text file.
After it finds the number of positive and negative words I am trying to get it to tally each up and then tell me if there are more positive or negative words found.
I have the code below so far, it only gives me a count on the positive words. I am not looking at something like NLP at this stage just something on a much more basic level.
I think I have the second part looking for the negative words in the wrong location. And I think I need to use a boolean to tell me if there are more positive or negative words found, but I can't work out how to do it.
I am pretty stuck as I am new to Java, and programing in general.
Any help would be greatly appreciated.
package omgilisearch;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class SentimentTest {
public static void main(String[] args) throws Exception {
printAllCounts(
readWordFile("ConversationTest.txt", loadKeywords("PositiveWords.txt")));
}
public static void main1(String[] args) throws Exception {
printAllCounts(
readWordFile("ConversationTest.txt", loadKeywords("NegativeWords.txt")));
}
private static Map<String, Integer> readWordFile(
String fname, Set<String> keywords) throws FileNotFoundException
{
final Map<String, Integer> frequencyData = new TreeMap<String, Integer>();
for (Scanner wordFile = new Scanner(new FileReader(fname));
wordFile.hasNext();)
{
final String word = wordFile.next();
if (keywords.contains(word))
frequencyData.put(word, getCount(word, frequencyData) + 1);
}
return frequencyData;
}
private static void printAllCounts(Map<String, Integer> frequencyData) {
System.out.println("-----------------------------------------------");
System.out.println(" Occurrences Word");
for(Map.Entry<String, Integer> e : frequencyData.entrySet())
System.out.printf("%15d %s\n", e.getValue(), e.getKey());
System.out.println("-----------------------------------------------");
}
private static int getCount(String word, Map<String, Integer> frequencyData) {
return frequencyData.containsKey(word)? frequencyData.get(word) : 0;
}
private static Set<String> loadKeywords(String fname)
throws FileNotFoundException
{
final Set<String> result = new HashSet<String>();
for (Scanner s = new Scanner(new FileReader(fname)); s.hasNext();)
result.add(s.next());
return result;
}
}
You would have to have some array of so called "bad" words (wich are hard coded) and then iterate through the whole text file and compare every word in the array with the word you currently inspecting. If the word matches with one of the words in the array, then increase some variable that is holding the amount of badwords eg. badWords++;. I believe this approach should work.
package omgilisearch;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class SentimentTest {
public static void main(String[] args) throws Exception {
printAllCounts(
readWordFile("ConversationTest.txt"));
}
private static Map<String, Integer> readWordFile(String string) {
return null;
}
String[] goodWordsHolder = new String[3];{
goodWordsHolder[0] = "good"; goodWordsHolder[1] = "great";goodWordsHolder[2] = "excellent";
for(int iteration = 0; iteration < goodWordsHolder.length; iteration++) { String currentWordInText;
if(goodWordsHolder[iteration] == currentWordInText) { }// The word is a bad word } }
private static void printAllCounts(Map<String, Integer> frequencyData) {
System.out.println("-----------------------------------------------");
System.out.println(" Occurrences Word");
for(Map.Entry<String, Integer> e : frequencyData.entrySet())
System.out.printf("%15d %s\n", e.getValue(), e.getKey());
System.out.println("-----------------------------------------------");
}
}
package omgilisearch;
import java.io.*;
public class SentimentTest {
public static void main(String[] args) {
String[] lines = new String[0];
String path = "ConversationTest.txt";
BufferedReader br = null;
try {
File file = new File(path);
br = new BufferedReader(
new InputStreamReader(
new FileInputStream(file)));
String line;
while( (line = br.readLine()) != null ) {
lines = add(line, lines);
}
br.close();
} catch(IOException e) {
System.out.println("read error: " + e.getMessage());
}
print(lines);
}
private static String[] add(String s, String[] array) {
String[] goodWordsHolder = new String[3];{
}goodWordsHolder[0] = "good"; goodWordsHolder[1] = "great";goodWordsHolder[2] = "excellent";
for(int iteration = 0; iteration < goodWordsHolder.length; iteration++) { String currentWordInText = null; if(goodWordsHolder[iteration] == currentWordInText) { }}
return goodWordsHolder; }
private static void print(String[] data) {
for(int i = 0; i < data.length; i++)
System.out.println(data[i]);
}
}
Arrays store multiple items of the same information type eg. String[] badWords;. I believe you should use this, since I'm sure you will have more than 1 bad word that you would like to find in the conversation text, if not, then simple use 1 String eg. String badWord;.
I'm not going to write out all the code that will make it work, I'll just give you an algorithm.
public class test {
// The process of picking out all the good and bad words
public static void main(String[] args) {
// Setting up all the needed variables
// Set up all the good words
String[] goodWordsHolder = new String[2];
goodWordsHolder[0] = "firstGoodWord";
goodWordsHolder[1] = "secondGoodWord";
// Set up all the bad words
String[] badWordsHolder = new String[2];
badWordsHolder[0] = "firstBadWord";
badWordsHolder[1] = "secondBadWord";
// Set up the counters
int amountOfGoodWords = 0;
int amountOfBadWords = 0;
int currentWordInText = 0;
// boolean that will exit the loop
boolean ConversationEnded = false;
while(!ConversationEnded) {
// Compare the currentWord from the conversation with the hard coded words
for(int iteration = 0; iteration < goodWordsHolder.length; iteration++) {
if(goodWordsHolder[iteration] == getWordInText(currentWordInText)) {
amountOfGoodWords++;
}
}
for(int iteration = 0; iteration < badWordsHolder.length; iteration++) {
if(badWordsHolder[iteration] == getWordInText(currentWordInText)) {
amountOfBadWords++;
}
}
// Increase the current word value so the next time we compare the next word in the conversation will be compared
currentWordInText++;
// Check that we haven't reached the end of the conversation
if(endOfTheConversationHasBeenReached()) {
// This will exit the while loop
ConversationEnded = true;
}
}
// Now print all the information to the console
System.out.println("Amount of good Words: " + amountOfGoodWords);
System.out.println("Amount of bad Words: " + amountOfBadWords);
if(amountOfGoodWords > amountOfBadWords) {
System.out.println("There are more good words than bad words.");
}
else {
System.out.println("There are more bad words than good words.");
}
}
// The method(s) you'll have to code out yourself. I suggest you read up on the web and so on to assist you with this.
private static String getWordInText(int currentWordInText) {
// TODO Auto-generated method stub
return null;
}
private static boolean endOfTheConversationHasBeenReached() {
// TODO Auto-generated method stub
return false;
}
}
Excuse me if there are any logical errors. The code hasn't been debugged yet. ;) Hopefully this will guide you into the right direction.