Returning the nth Token - java

I'm very new at Java and I have a question about a summer assignment. These are the instructions:
Write a class called SpecialToken that has a static method called thirdToken. This
method should return as a String, the third token of a String that you pass as a parameter.
You may assume that spaces will serve as delimiters.
This is what I have so far but honestly I am stumped at what the parameter should be and how to return the third token! I was thinking I could do something like nextToken() until the third.
public class SpecialToken {
public static String thirdToken() {
}
}

Try something like
public class SpecialToken {
public static String thirdToken(String str) {
String[] splited = str.split(" ");
return splited[2];
}
}
Also see this tutorial or try searching google for "java split string into array by space"
Also note, as Betlista said this does not have any error checking, so if the passed string only has two tokens delimited by one space, you will get an Array out of bounds exception.
Or an other way would be to "Use StringTokenizer to tokenize the string. Import java.util.StringTokenizer. Then create a new instance of a StringTokenizer with the string to tokenize and the delimiter as parameters. If you do not enter the delimiter as a parameter, the delimiter will automatically default to white space. After you have the StringTokenizer, you can use the nextToken() method to get each token. " via Wikihow
With this method, your code should look something like this:
public class SpecialToken {
public static String thirdToken(String str) {
StringTokenizer tok = new StringTokenizer(str); // If you do not enter the delimiter as a parameter, the delimiter will automatically default to white space
int n = tok.countTokens();
if (n < 3) {return "";}
tok.nextToken();
tok.nextToken();
return tok.nextToken();
}
}
However keep in mind Wikihow's warning "now, the use of StringTokenizer is discouraged and the use of the split() method in the String class or the use of the java.util.regex package is encouraged."

Related

How can I fix the startsWith() error of java

I cannot figure out the startsWith(str) in the while loop below have the error
The method startsWith(String) is undefined for the type InfoProcessor.
I want to get the String that follows the line that starts with the given String (str).
It is great pleasure to have your help.
import java.util.*;
public class InfoProcessor {
private ArrayList<String> lines = new ArrayList<String>();
public InfoProcessor(ArrayList<String> lines) {
this.lines = lines;
}
String getNextStringStartsWith(String str) {
for (int i = 0 ; i < lines.size(); i++){
Scanner scanner = new Scanner(lines.get(i));
while (startsWith(str)){
String hobby = scanner.nextLine();
String[] tokens = hobby.split("\\s+");
return tokens[1];
}
}
return null;
}
You are trying to invoke a String method but you are not invoking it on a String. Therefore, the compiler interprets your attempt as invoking the method on this class. This class does not implement that method so the method is undefined. In your case, you want to invoke that method on an individual line to see if it contains the prefix.
public String findWordAfterPrefix(String prefix) {
for (String line : lines) { // iterate over the lines
if (line.startsWith(prefix)) { // does the line start with the prefix?
/// find the next word and return it - that is a separate issue! ;)
}
}
return null; // return null if we never found the prefix
}
p.s. You may find some other String method useful as you pull out the next word (e.g. trim(), substring(int).
The error means exactly what it says: there is no startsWith() method in your InfoProcessor class.
You may have intended str.startsWith(...) instead of startsWith(str).

How to pass text file data from one class to another

I'm trying to create a program that reads a text file and then outputs stats about the text file. I'm getting stuck on the beginning. In this assignment, we were told that we just need to read using the scanner in one class and the create "tokens" to be passed and used in other classes for calculations. I'm not entirely sure how to do that. This is my code so far for reading the file inside one class:
private String s;
public void analyzeBookText(Scanner input) {
while(input.hasNext()) {
input.useDelimiter(".|!|?");
s = input.next();
if(input.next().equals("$$$END$$$")) {
break;
}
}
}
public String getS() {
return s;
}
So I have string s be just one sentence. Then I'm trying to access s in a different class by creating a String instance variable and this constructor:
public SentenceTally() {
BookMain sentence = new BookMain();
s = sentence.getS();
}
However, when I try to use s in other methods I get a stackoverflow error. How can I properly use data from the scanner in one class in methods for another class? Thanks!
You are half way there. Next, what you need is to read the text file and store it into an array. Since your school mentioned tokens, you may read line by line from the text file, then split each line (if your data file only has one line, then just tokenize that one line of data) into tokens (represented as array):
String[] tokens = line.split(delimiter);
You may need to convert the tokens to int array or double array first being using it for calculations.
Pass tokens array as an argument to your other methods for calculation:
public void calculate(int[] tokens){
//your calculations in Java
}
To pass your data to other classes:
BookMain book = new BookMain();
book.analyzeFile(yourScanner);
SomeClass c = new SomeClass();
c.calculate(book.getTokens()); //create a getter for tokens in BookMain first

regex is not working in guava

I am using guava 21.0 and trying to split a String by providing a regex(\\d).
However,I am not sure why is not working.
If I change regex to anything which is not regex (eg "a") then it works fine.
Here is the code :
public class SplitWithRegex {
public static Iterable<String> splitByRegex(String string, String regex){
return Splitter.on(regex).trimResults().omitEmptyStrings().split(string);
}
public static void main(String[] args) {
Iterable<String> itr = splitByRegex("abc243gca87asas**78sassnb32snb1ss22220220", "\\d");
for(String s : itr){
System.out.println(s);
}
}
}
Result when regex is applied :
abc243gca87asas**78sassnb32snb1ss22220220
Any help would be appreciated.
You must use Splitter.onPattern("\\d+") and not Splitter.on("\\d+").
Here's the javadoc for Splitter's on method, this is what it says:
Returns a splitter that uses the given fixed string as a separator.
For example, Splitter.on(", ").split("foo, bar,baz") returns an
iterable containing ["foo", "bar,baz"].
So, separator is a treated as String literal and not regex and hence, it does not split the String as expected. If you want regex based splitting then you can use String's split method or Splitter's onPattern method, e.g.:
String[] tokens = "abc243gca87asas**78sassnb32snb1ss22220220".split("\\d+");
for(String token : tokens){
System.out.println(token);
}
public static Iterable<String> splitByRegex(String string, String regex){
return Splitter.onPattern(regex).trimResults().omitEmptyStrings().split(string);
}

Remove part of string after or before a specific word in java

Is there a command in java to remove the rest of the string after or before a certain word;
Example:
Remove substring before the word "taken"
before:
"I need this words removed taken please"
after:
"taken please"
String are immutable, you can however find the word and create a substring:
public static String removeTillWord(String input, String word) {
return input.substring(input.indexOf(word));
}
removeTillWord("I need this words removed taken please", "taken");
There is apache-commons-lang class StringUtils that contains exactly you want:
e.g. public static String substringBefore(String str, String separator)
public static String foo(String str, String remove) {
return str.substring(str.indexOf(remove));
}
Clean way to safely remove until a string
String input = "I need this words removed taken please";
String token = "taken";
String result = input.contains(token)
? token + StringUtils.substringAfter(string, token)
: input;
Apache StringUtils functions are null-, empty-, and no match- safe
Since OP provided clear requirements
Remove the rest of the string after or before a certain word
and nobody has fulfilled those yet, here is my approach to the problem. There are certain rules to the implementation, but overall it should satisfy OP's needs, if he or she comes to revisit the question.
public static String remove(String input, String separator, boolean before) {
Objects.requireNonNull(input);
Objects.requireNonNull(separator);
if (input.trim().equals(separator)) {
return separator;
}
if (separator.isEmpty() || input.trim().isEmpty()) {
return input;
}
String[] tokens = input.split(separator);
String target;
if (before) {
target = tokens[0];
} else {
target = tokens[1];
}
return input.replace(target, "");
}

alternate method for using substring on a String

I have a string which contains an underscore as shown below:
123445_Lisick
I want to remove all the characters from the String after the underscore. I have tried the code below, it's working, but is there any other way to do this, as I need to put this logic inside a for loop to extract elements from an ArrayList.
public class Test {
public static void main(String args[]) throws Exception {
String str = "123445_Lisick";
int a = str.indexOf("_");
String modfiedstr = str.substring(0, a);
System.out.println(modfiedstr);
}
}
Another way is to use the split method.
String str = "123445_Lisick";
String[] parts = string.split("_");
String modfiedstr = parts[0];
I don't think that really buys you anything though. There's really nothing wrong with the method you're using.
Your method is fine. Though not explicitly stated in the API documentation, I feel it's safe to assume that indexOf(char) will run in O(n) time. Since your string is unordered and you don't know the location of the underscore apriori, you cannot avoid this linear search time. Once you have completed the search, extraction of the substring will be needed for future processing. It's generally safe to assume the for simple operations like this in a language which is reasonably well refined the library functions will have been optimized.
Note however, that you are making an implicit assumption that
an underscore will exist within the String
if there are more than one underscore in the string, all but the first should be included in the output
If either of these assumptions will not always hold, you will need to make adjustments to handle those situations. In either case, you should at least defensively check for a -1 returned from indexAt(char) indicating that '_' is not in the string. Assuming in this situation the entire String is desired, you could use something like this:
public static String stringAfter(String source, char delim) {
if(source == null) return null;
int index = source.indexOf(delim);
return (index >= 0)?source.substring(index):source;
}
You could also use something like that:
public class Main {
public static void main(String[] args) {
String str = "123445_Lisick";
Pattern pattern = Pattern.compile("^([^_]*).*");
Matcher matcher = pattern.matcher(str);
String modfiedstr = null;
if (matcher.find()) {
modfiedstr = matcher.group(1);
}
System.out.println(modfiedstr);
}
}
The regex groups a pattern from the start of the input string until a character that is not _ is found.
However as #Bill the lizard wrote, i don't think that there is anything wrong with the method you do it now. I would do it the same way you did it.

Categories