I have an ArrayList,where I search for needed element and then add the needed part of it to another ArrayList. The problem is that if I want to keep searching for the words,not only one word,I don't know how to keep going on the elements through the loop. With the using of iterator, I wouldn't be able to search for things I need.
public static ArrayList<String> FindWord(){
ArrayList<String> rewrite=new ArrayList<>();//
ArrayList<String> word=Reading();// rewrites the data from one string to other
String userinput=Chat();
for(String elmt:word){
if (elmt.contains(userinput) && elmt.contains("=")) {
String[] parts=elmt.split("\\=");
rewrite.add(parts[1]);
// here I must do something like word.next
}
}
System.out.println(rewrite);
return rewrite; // RETURNS THE SYNONIM OF THE WORD
}
So,it goes like if I input "hello", it will find me the word "greeting",which is a synonim in my text file. If I input "awesome", it will find the word "thanks", but if I input both of them it will input an empty array, like nothing is found instead of " greeting, thanks"
UPD:
The Reading() returns:
public static ArrayList<String> Reading() {
Scanner inputreader = null;
try {
inputreader = new Scanner(new FileInputStream("D:\\sinonims.txt"));
}catch (FileNotFoundException e1) { // OPENS FILE WITH SINONIMS
e1.printStackTrace();
System.out.println("File not found");
System.exit(0);
}
ArrayList<String> Sins=new ArrayList();
while(inputreader.hasNextLine()){
String l=inputreader.nextLine();
Sins.add(l); // REWRITES DATA FROM FILE TO ARRATLIST
}
inputreader.close();
System.out.print(Sins);
return Sins;
}
public static String Chat(){
System.out.println("Let's start talking.");
Scanner in=new Scanner(System.in);
String line=in.nextLine();
return line;
}
If you are trying to accept many inputs, you'll need to loop around the input & for loop.
The for loop already loops over all the words.
Note: I replaced contains for startsWith to prevent you catching the word on the other side of the equals
static ArrayList<String> word=Reading();
public static ArrayList<String> FindWord(){
ArrayList<String> rewrite=new ArrayList<>();
String userinput = "" ;
while (true) {
userinput=Chat();
if (userinput.equals("quit")) break;
for(String elmt:word){
if (elmt.startsWith(userinput) && elmt.contains("=")) {
String[] parts=elmt.split("\\=");
rewrite.add(parts[1]);
}
}
System.out.println(rewrite);
return rewrite; // RETURNS THE SYNONIM OF THE WORD
}
I can't really say this is the best way to approach your problem because it seems you need a Hashmap, not an Arraylist
contains fetches you exact match, split the text and match accordingly, store the results in new array list
you can create another arraylist and add your userinput values one by one into that list . you can iterate this newly created arraylist by using new for each loop on top of the current for each loop.
You should split the input string userinput with some specific delimiter.
Then for each word, Iterate through the splitted array and give each word as input , Find its Synonym with your technique and add it to the arraylist.
This can be implemented by doing some changes in your code.
public static ArrayList<String> FindWord()
{
ArrayList<String> rewrite=new ArrayList<>();
ArrayList<String> word=Reading();
String userinput=Chat();
String inputs[]=userinput.split(","); //Considering delimiter is comma(",") in user input
for(String input : inputs) //Giving each word as input at a time and search for it in word String
{
for(String elmt:word)
{
if (elmt.contains(input) && elmt.contains("="))
{
String[] parts=elmt.split("\\=");
rewrite.add(parts[1]);
}
}
}
System.out.println(rewrite);
return rewrite; // RETURNS THE SYNONIM OF THE WORD
}
So Here I am considering that the input is with delimiter Comma(",") so I have splitted input string with Comma(",") as you have given description in comments about your problem with space as delimiter.
When you will print the ArrayList, Automatically Output will be printed in separated manner with comma(, ).
So for Input : hello,awesome It will give output as greeting, thanks.
Related
I have a method which takes input via a scanner, formats with toUpperCase and splits on whitespace.
It also takes an input limit. So only the first N words will appear in the outputted array.
public String[] getMultiLineInput(int inputLimit)
String[] input = Arrays.stream(scanner.nextLine().toUpperCase().split("\\s+"))
.limit(inputLimit)
.toArray(size -> new String[inputLimit]);
return input;
}
My method works as intended however I would now like to add an additional condition. That if the String retrieved by scanner.nextline() is smaller than the input limit. Then it will trim it even further to avoid NULL entries in my String[]
public String[] getMultiLineInput(int inputLimit){
System.out.println("> ");
String[] input = Arrays.stream(scanner.nextLine().toUpperCase().split("\\s+"))
.limit(inputLimit)
.toArray(size -> new String[inputLimit]);
ArrayList<String> temp = new ArrayList<>();
for ( String word : input){
if ( word != null){
temp.add(word);
}
}
String [] trimmedarray = temp.toArray(new String[temp.size()]);
return trimmedarray;
}
Is there a more concise/efficient way of doing this with streams + lamda (new to java 8)?. Is there a way of this additional step being included into my stream?.
When calling to array don't specify the length yourself. Use method reference instead which makes your code even more readable:
public String[] getMultiLineInput(int inputLimit) {
String[] input = Arrays.stream(scanner.nextLine().toUpperCase().split("\\s+"))
.limit(inputLimit)
.toArray(String[]::new);
return input;
}
Or as #Naman suggested:
public String[] getMultiLineInput(int inputLimit) {
return Arrays.stream(scanner.nextLine().toUpperCase().split("\\s+"))
.limit(inputLimit)
.toArray(String[]::new);
}
I need to use ArrayLists to count the words in a text file and display their frequency. I would like to start by creating the ArrayList of "Word" objects. From that point I shouldn't have an issue. The problem I am encountering is when adding an object to the list. I receive an error stating "The method add(Word) in the type ArrayList is not applicable for the arguments (String)"
public ArrayList<Word> wordList = new ArrayList<Word>();
String fileName, word;
int counter;
Scanner reader = null;
Scanner scanner = new Scanner(System.in);
public void analyzeText() {
System.out.print("Please indicate the file that you would like to analyze (with the path included): ");
fileName = scanner.nextLine();
try {
reader = new Scanner(new FileInputStream(fileName));
}
catch(FileNotFoundException e) {
System.out.println("The file could not be found. The program will now exit.");
System.exit(0);
}
while (reader.hasNext()) {
word = reader.next().toLowerCase();
wordList.add(word);
counter++;
}
}
public class Word {
String value;
int frequency;
public Word(String v) {
value = v;
frequency = 1;
}
}
You need to add a Word Object not a String:
word = reader.next().toLowerCase();
Word myNewWord = new Word(word); /*Generates a Word Object using your constructor*/
wordList.add(myNewWord);
counter++
Hope that helps.
wordList is an array of "Word" objects. But in line 17
wordList.add(word);
you're adding another type of content into the array (a string).
Note there's an object-type, named "Word" (uppercase), and another variable named
"word" (lowercase) of type string.
You're adding a string "word" to the array list, but in this case you can add only objects "Word" to the ArrayList of name wordList.
You need to add Word object to your list. But you are assigning a string which is readed from scanner. You need to create a Word object.
I think, your solution for counting word is wrong. You are using wrong data structure. Hashmap fits better for this case. You can assign words as a key and count of words as a value.
How I can add elements to a list from a input in java.
Like if i put:
Scanner reader = new Scanner("a,b,c,d,e);
I want to Have it like String[] a = {a,b,c,d,e];
Using any Scanner Methods with whiles , Really i am little bit lost
Sorry for my English( is not my main language)
If you know how many input items you are going to accept, declare an array before you start the input, then put each input into the array until you run out of array space.
The better way to do this is to use ArrayList:
ArrayList<String> inputList = new ArrayList<String>();
Using a Scanner, you can retrieve the next input (if you want an entire line, use reader.nextLine() to get that string. I'd suggest storing that in a local variable temporarily so you can examine it if you need to (you'll need some sort of termination sentinel or use hasNextLine() to see if there is more to read.
If you then need to return as an array, ArrayList has a toArray() method you can call.
To add inputs to list like this
import java.util.ArrayList;
import java.util.Scanner;
public class StackOverflow {
public static void main(String[] args) {
ArrayList<String> inputList = new ArrayList<String>();
Scanner reader = new Scanner(System.in);
String input = reader.nextLine();
inputList.add(input);
while (!input.equals("null")) {
input = reader.nextLine();
inputList.add(input);
}
}
}
This should work, the default token used by Scanner is whitespace characters.
public String[] getStringArray(String input, int arraySize) {
String[] stringArray = new String[arraySize];
Scanner s = new Scanner(input);
for (int i = 0; s.hasNext(); i++) {
stringArray[i] = s.next();
}
s.close();
return stringArray;
}
So I have a problem that takes the names of people from a user and stores them in an ArrayList(personalNames). After that I need to take that list and remove any name that has anything besides letters a-z (anything with numbers or symbols) in it and put them into a separate ArrayList(errorProneNames) that holds the errors. Could someone help me with the removal part?
public class NameList {
public static void main(String[] args) {
ArrayList<String> personalNames = new ArrayList<String>();
Scanner input = new Scanner(System.in);
String answer;
do{
System.out.println("Enter the personal Names: ");
String names = input.next();
personalNames.add(names);
System.out.println("would you like to enter another name (yes/no)?");
answer = input.next();
} while (answer.equalsIgnoreCase("yes"));
ArrayList<String> errorProneNames = new ArrayList<String>();
}
}
If it's the "how do I remove an element from an ArrayList<>" part which is causing problems, and you want to check all the values, you probably want to use an Iterator and call remove on that:
for (Iterator<String> iterator = personalNames.iterator(); iterator.hasNext(); ) {
String name = iterator.next();
if (isErrorProne(name)) {
iterator.remove();
}
}
Note that you mustn't remove an element from a collection while you're iterating over it in an enhanced-for loop except with the iterator. So this would be wrong:
// BAD CODE: DO NOT USE
for (String name : personalNames) {
if (isErrorProne(name)) {
personalNames.remove(name);
}
}
That will throw a ConcurrentModificationException.
Another option would be to create a new list of good names:
List<String> goodNames = new ArrayList<>();
for (String name : personalNames) {
if (!isErrorProne(name)) {
goodNames.add(name);
}
}
Now, if your real problem is that you don't know how to write the isErrorProne method, that's a different matter. I suspect that you want to use a regular expression to check that the name only contains letters, spaces, hyphens, and perhaps apostrophes - but you should think carefully about exactly what you want here. So you might want:
private static boolean isErrorProne(String name) {
return !name.matches("^[a-zA-Z \\-']+$");
}
Note that that won't cope with accented characters, for example. Maybe that's okay for your situation - maybe it's not. You need to consider exactly what you want to allow, and adjust the regular expression accordingly.
You may also want to consider expressing it in terms of whether something is a good name rather than whether it's a bad name - particularly if you use the last approach of building up a new list of good names.
Here is your solution :
String regex = "[a-zA-Z]*";
for (String temp : personalNames ) {
if (!temp.matches(regex)){
errorProneNames.add(temp);
personalNames.remove(temp);
}
}
You can use the remove() method of ArrayList
personalNames.remove("stringToBeRemoved");
Lot of overloaded methods are available. You can delete with index, Object(String itself) etc. You can see Javadocs for more info.
Also to remove all String having anything but a-z letters you can use regex. Logic is as follows
String regex = "[a-zA-Z]*";
String testString = "abc1";
if(!testString.matches(regex)){
System.out.println("Remove this");
}
As Jon pointed out while iterating over the List do not use the Lists's remove() method but the iterators remove() method.
There are two ways you can do this:
The first is to iterate backwards through the list, remove them, then add them into the second list. I say to do it backwards, because it will change the index.
for (int i = personalNames.size()-1; i >=0; i++) {
if (isBadName(personalNames.get(i)]){
errorProneNames.add(personalNames.get(i));
personalNames.remove(i);
}
}
The second way is to use the Iterator provided by ArrayList (personalNames.iterator()). This will allow you to go forward.
I would probably do this
// Check that the string contains only letters.
private static boolean onlyLetters(String in) {
if (in == null) {
return false;
}
for (char c : in.toCharArray()) {
if (!Character.isLetter(c)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
ArrayList<String> personalNames = new ArrayList<String>();
ArrayList<String> errorProneNames = new ArrayList<String>(); // keep this list here.
Scanner input = new Scanner(System.in);
String answer;
do {
System.out.println("Enter the personal Names: ");
String names = input.next();
if (onlyLetters(names)) { // test on input.
personalNames.add(names); // good.
} else {
errorProneNames.add(names); // bad.
}
System.out
.println("would you like to enter another name (yes/no)?");
answer = input.next();
} while (answer.equalsIgnoreCase("yes"));
}
get an iterator from list, while itr has next element give it to a method for example isNotProneName which takes a String and returns true or false, if the given String matches not your needs. if false returned remove string from itr and add it to the other list
Use regex [a-zA-Z ]+ with String.matches to test error-prone name and Iterator to remove.
Iterator<String> it=personalNames.iterator();
while(it.hasNext()){
String name=it.next();
if(name.matches("[a-zA-Z ]+")){
it.remove();
}
}
I am looking for a way to read a tab delimited file of baseball stats into a two dimensional arraylist. I'm using a scanner to read the file, but I can't think of how to read just one line into an array list, stopping at the line break, then read the next line into the next arraylist.
This is my first time trying to create a multidimensional arraylist, and I thought it would be much the same as reading multidimensional arrays. I was clearly mistaken.
public static ArrayList dataRead(String fileloc) throws FileNotFoundException {
ArrayList array = new ArrayList<ArrayList>();
Scanner s = new Scanner(new File(fileloc)).useDelimiter("\t");
ArrayList<String> rows = new ArrayList<String>();
ArrayList cols = new ArrayList();
while(s.nextLine() != null) {
cols.add(s.next());
}
return array;
}
This is my code as of now. Would it be a better choice to read each line into a string, delimited by returns, then read each string into an appropriate arraylist?
You could use opencsv and set the delimeter to tab. Check out the examples on the link I provided.
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t');
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
}
Although it's not clear from your question what your actual issue is when trying to 'roll your own'
I'm not sure what the stats look like, but it might be better to use a HashMap which has Key/value pairs instead, but I could be wrong. I don't know what your dataset looks like.
For a start, you can delimit the lines by using the "\t" escape character.
For Example:
Scanner s = new Scanner(input).useDelimiter("\t");
Then you can loop through the results and for every pair add it to the map.
I think you need to rethink your data structure to something more conducive to what you are trying to store. I would recommend that you create a player object and store that into an arraylist.
public class Player{
double battavg;
String name;
//add more values like rbi, etc.
public Player(name,battavg){
this.name=name;
this.battavg=battavg;
}
public String getName(){
return name;
}
public String getBattAvg(){
return battavg;
}
public setBattAvg(double battavg){
this.battavg=battavg;
}
public setName(String name){
this.name=name;
}
}
public class baseball{
public static void main(String[] args){
ArrayList<Player> list = new ArrayList<Player>();
//read in values from csv
list.add(new Player(name,battavg));
}
}