How to take StringTokenizer result to ArrayList in Java? - java

I want to take StringTokenizer result to ArrayList. I used following code and in 1st print statement, stok.nextToken() print the correct values. But, in second print statement for ArrayList give error as java.util.NoSuchElementException .
How I take these results to an ArrayList?
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Test {
public static void main(String[] args) throws java.io.IOException {
ArrayList<String> myArray = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter : ");
String s = br.readLine();
StringTokenizer stok = new StringTokenizer(s, "><");
while (stok.hasMoreTokens())
System.out.println(stok.nextToken());
// -------until now ok
myArray.add(stok.nextToken()); //------------???????????
System.out.println(myArray);
}
}

Quoting javadoc of StringTokenizer:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
"New code" meaning anything written for Java 1.4 or later, i.e. ancient times.
The while loop will extract all values from the tokenizer. When you then call nextToken() after already having extracted all the tokens, why are you surprised that you get an exception?
Especially given this quote from the javadoc of nextToken():
Throws NoSuchElementException if there are no more tokens in this tokenizer's string.
Did you perhaps mean to do this?
ArrayList<String> myArray = new ArrayList<>();
StringTokenizer stok = new StringTokenizer(s, "><");
while (stok.hasMoreTokens()) {
String token = stok.nextToken(); // get and save in variable so it can be used more than once
System.out.println(token); // print already extracted value
// more code here if needed
myArray.add(token); // use already extracted value
}
System.out.println(myArray); // prints list

ArrayList<String> myArray = new ArrayList<String>();
while (stok.hasMoreTokens()){
myArray.add(stok.nextToken());
}
dont call stock.nextToken outside the while loop that results in exceptions and printing out arraylist in System.out.println wont help you have to use a for loop.
for(String s : myArray){
System.out.Println(s);
}

Related

Ignore numbers in a text file when scanning it in Java

I am doing an assignment in Java that requires us to read two different files. One has the top 1000 boy names, and the other contains the top 1000 girl names. We have to write a program that returns all of the names that are in both files. We have to read each boy and girl name as a String, ignoring the number of namings, and add it to a HashSet. When adding to a HashSet, the add method will return false if the name to be added already exists int he HashSet. So to find the common names, you just have to keep track of which names returned false when adding. My problem is that I can't figure out how to ignore the number of namings in each file. My HashSet contains both, and I just want the names.
Here is what I have so far.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Names {
public static void main(String[] args) {
Set<String> boynames = new HashSet<String>();
Set<String> girlnames = new HashSet<String>();
boynames = loadBoynames();
System.out.println(girlnames);
}
private static Set<String> loadBoynames() {
HashSet<String> d = new HashSet<String>();
File names = new File("boynames.txt");
Scanner s = null;
try {
s = new Scanner(names);
} catch (FileNotFoundException e) {
System.out.println("Can't find boy names file.");
System.exit(1);
}
while(s.hasNext()){
String currentName = s.next();
d.add(currentName.toUpperCase());
}
return d;
}
}
My plan is to take the HashSet that I currently have and add the girl names to it, but before I do I need to not have the numbers in my HashSet.
I tried to skip numbers with this code, but it just spat out errors
while(s.hasNextLine()){
if (s.hasNextInt()){
number = s.nextInt();
}else{
String currentName = s.next();
d.add(currentName.toUpperCase());
}
}
Any help would be appreciated.
You could also use regex to replace all numbers (or more special chars if needed)
testStr = testStr.replaceAll("\\d","");
Try to use StreamTokenizer (java.io) class to read file. it will split your file into tokens and also provide type of token like String value, number value in double data type, end of file, end of line). so you can easily identify the String token.
You can find details from here
http://docs.oracle.com/javase/6/docs/api/java/io/StreamTokenizer.html

how to retrieve a line with spaces with comma as separator?

I have this record in my game.txt file
menard,menard mabunga,0
francis,francis mabunga,0
angelica,francis mabunga,1
I access the file and store it in an array list using this code;
Scanner s = new Scanner(getResources().openRawResource(R.raw.game));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext()){
list.add(s.next());
}
s.close();
And use this function to load a random line;
public static String randomLine(ArrayList list) {
return (String) list.get(new Random().nextInt(list.size()));
}
When I try to print the result of the randomLine function using System.out.println(randomLine(list)); the output is mabunga,0 only.
Now, how can I retrieve a line with spaces with comma as separator?
You are reading words instead of lines. Use nextLine() instead of next(). So, this should be your code:
Scanner s = new Scanner(getResources().openRawResource(R.raw.game));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext()){
list.add(s.nextLine()); // Change here!!
}
s.close();
I prefer BufferedReader over Scanner if the goal is to read lines.
You should instantiate Random ony once, and store a reference to it. Otherwise, nextInt() will always return the same value.
Use a String Tokenizer (or a Stream Tokenizer if you want to separate them while reading the file). Set the separator to ",". Then you should be fine.
In the randomLine function use the following piece of code, instead of yours:
public static String randomLine(ArrayList list) {
return (String) list.get((int)(Math.Random()*list.size()));
}

Limiting an Array

This is my code below, I get an java.lang.IndexOutOfBoundsException & I can't fix it? I am supposed to STOP the error from coming up because I have over 100 names in the file!
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ArrayPractice1 {
public static void main(String[] args) throws FileNotFoundException
{
String[] names = new String[100];
Scanner scan = new Scanner(new File("names.txt"));
int index = 0;
while (scan.hasNext()){
names[index]=(scan.nextLine());
index++;
}
for(int i = 0; i <index -1; i++){
System.out.println(names[i]);
}
}
}
youre not working with an ArrayList of Strings, you're working with a plain array of Strings.
seems like youre getting more than 100 items from scan.hasNext() and so you eventually try to access names[100] and get the exception you describe
instead, you could use this:
ArrayList<String> names = new ArrayList<String>();
and then
while (scan.hasNext()){
names.add(scan.nextLine());
}
and you wont have to worry about knowing the exact size beforehand
If the size of the input is not known at compile time, consider using an ArrayList instead of an array.
Just add the elements to the ArrayList using names.add(scan.nextLine()):
ArrayList<String> names = new ArrayList<String>();
while (scan.hasNext()) {
names.add(scan.nextLine())
}
You are giving 100 as the size of array.If your file have more than 100 lines, definitely it will throw exception
change the condition in your while loop to
while (scan.hasNext() && index < 100)
this will stop the read loop after you fill up the array
Why not making it independent from any upper limit? Use an ArrayList:
ArrayList<String> names = new ArrayList<String>();
Scanner scan = new Scanner(new File("names.txt"));
while (scan.hasNext()){
names.add(scan.nextLine());
}
for(String name : names){
System.out.println(name);
}

Regarding arrayList

I have used scanner instead of string tokenizer ,, below is the piece of code...
Scanner scanner = new Scanner("Home,1;Cell,2;Work,3");
scanner.useDelimiter(";");
while (scanner.hasNext()) {
// System.out.println(scanner.next());
String phoneDtls = scanner.next();
// System.out.println(phoneDtls);
ArrayList<String> phoneTypeList = new ArrayList<String>();
if(phoneDtls.indexOf(',')!=-1) {
String value = phoneDtls.substring(0, phoneDtls.indexOf(','));
phoneTypeList.add(value);
}
Iterator itr=phoneTypeList.iterator();
while(itr.hasNext())
System.out.println(itr.next());
}
The ouput I get upon executing this...
Home
Cell
Work
As it is seen from the above code is that in the array list phoneTypeList we are finally storing the values..but the logic of finding out the value on the basisi of ',' is not that much great..that is ..
if(phoneDtls.indexOf(',')!=-1) {
String value = phoneDtls.substring(0, phoneDtls.indexOf(','));
phoneTypeList.add(value);
}
could you please advise me with some other alternative ..!! to achieve the same thing...!!thanks a lot in advance..!!
Well, since you asked if there is another way to do it then here is an alternative: You can split the string directly and do it with less code with the foreach statement:
String input = "Home,1;Cell,2;Work,3";
String[] splitInput = input.split(";");
for (String s : splitInput ) {
System.out.println(s.split(",")[0]);
}
No need to use the ArrayList<T> since you can iterate over an array as well.
could you try to split based on ',' STIRNG_VALUE.split(','); will return u an array with strings separated with , may be this helps
If i understand correctly. The problem statement is you want to maintain a list of Phone-Type-List. Like this: ["Home", "Cell", "Work"].
I suggest you keep this in a property file / config file / database which ever makes sense and load it to memory on start of you app.
If the input cannot be changed then as for the algorithm i couldn't think of a better one. Looks good.
You could use split function of string if that makes sense.
First use split on ";"
Then a split on ","
declare the arraylist outside the while loop.
try this, i have made some change for better performance too. hope you can compare and understand the change.
ArrayList<String> phoneTypeList = new ArrayList<String>();
Scanner scanner = new Scanner("Home,1;Cell,2;Work,3");
scanner.useDelimiter(";");
String phoneDtls = null;
String value = null;
while (scanner.hasNext()) {
phoneDtls = scanner.next();
if (phoneDtls.indexOf(',') != -1) {
value = phoneDtls.split(",")[0];
phoneTypeList.add(value);
}
}
Iterator itr = phoneTypeList.iterator();
while (itr.hasNext())
System.out.println(itr.next());
I have executed n got the result, check screenshot.

Type error using ArrayList?

package mp1similar;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import EarthquakeRecord.Earthquakerecd;
public class MP1Similar
{
private static ArrayList arrayList ;
public static void main(String[] args)
{
ArrayList arrayList= null;
try
{
BufferedReader br = new BufferedReader(new FileReader("data/Catalog.txt"));
String line="";
arrayList =new ArrayList();
while((line = br.readLine())!=null)
{
// System.out.println(line);
StringTokenizer st = new StringTokenizer(line);
while(st.hasMoreTokens())
{
//System.out.println(st.nextToken());
arrayList.add(st.nextToken());
//System.out.println(br.readLine());
}
}
}
catch (FileNotFoundException ex)
{
System.out.println(ex.getMessage());
ex.printStackTrace();
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
ex.printStackTrace();
}
int j=0;
Earthquakerecd E[]= new Earthquakerecd[2000];
for(int i=0;i< arrayList.size();i++)
{
System.out.println(arrayList.get(i));
E[j] = new Earthquakerecd();
E[j].setDate(arrayList.get(i));
if (j>35 )
{
j=0;
}
j++;
}
}
}
I am getting an error in the line E[j].setDate(arrayList.get(i)); It says that the actual argument cannot be converted to java.lang.String by method invocation.
All the fields in the object are String Types. The arrayList contains all the data extracted from the TXT file. I am trying to transfer all the data from the arrayList to the object array. The txt file has 35 columns and 1500 rows. The data being seperated by whitespace
Change:
ArrayList arrayList = null;
...
arrayList =new ArrayList();
to:
ArrayList<String> arrayList = null;
arrayList = new ArrayList<String>();
or just:
ArrayList<String> arrayList = new ArrayList<String>();
A List contains Object instances. The get() method returns Object. If you want a typesafe List, you must use the generic type information:
List<String> list = new ArrayList<String>();
If you use the raw type (without the <String> generic type information), then the compiler doesn't know that the List only contains String instances, and you thus have to cast the result:
String s = (String) list.get(i);
Side note: learn to indent your code and to respect Java naming conventions. It's unreadable as is.
I think the problem is that you're using the raw ArrayList type rather than using a parameterized ArrayList. Consequently, all operations on the ArrayList will assume that the parameter and returns types are Object rather than String, since you haven't indicated to Java that you want the ArrayList to hold Strings. Without this extra information from you, Java can't know that the objects stored within are exclusively Strings and not, say, Integers, other ArrayLists, JPanels, etc.
To fix this, change the line
private static ArrayList arrayList;
to read
private static ArrayList<String> arrayList;
This explicitly indicates to Java that your ArrayList should only hold Strings, so it can know that the return type of arrayList.get(i) is going to be a String rather than the catch-all Object. Similarly, change
arrayList = new ArrayList();
to
arrayList = new ArrayList<String>();
For more information, read up on Java Generics. They're a very powerful tool, but can easily be used improperly (as in your case). One nice source is this article by Oracle.
Hope this helps!
ArrayList<String> arrayList= null;
ArrayList get call returns an Object unless you specify the type.
Diamond was added in Java 7 :
ArrayList<String> arrayList = new ArrayList<>();

Categories