Parse String to Integer throws NullpointerException - java

Hy!
I want to parse a String to a Integer.
The String is like the format for series: SXXEXXX
The Code should increase the episode.
Like: S01E01 --> S01E02
Also: S01E100 --> S01E101
Code:
String s = episodes.get(episodes.size()-1);
Log.e("DBManager",s);
if (s.split("E").length <= 2) {
int i = Integer.getInteger(s.split("E")[1].split(" ")[0]); //NullPointerEx
return s.split("E")[0]+"E"+String.valueOf(i++);
}
Log:
10-26 15:56:34.635: E/DBManager(932): S00E01

Integer.getInteger() is not the correct method to use.
You should be using Integer.valueOf()
Integer.getInteger(String s) will return the integer system property with the key s.
The null pointer occurs because this method can't find the property with the key you supply and returns null. Java then tries to unbox this to an int and null pointers.

The null pointer exception is occuring precisely because you leave the leading 0 in the string. If you really need to leave it in there though, the following code works for me:
int i = Integer.parseInt(s.split("E")[1].split(" ")[0]);

If I understand correctly, you want to split the episode name into the parts, then get the episode number and increment it by one to get the next episode number. Don't call this split method so many times, call it once.
String episodeName = episodes.get(episodes.size()-1);
Log.e("DBManager", episodeName);
string[] splittedName = episodeName.split("E");
string returnName = "";
if (splittedName.length == 2) {
if (splittedName[1].split(" ").length > 1) {
// do something if there's a episode name too
} else {
// gets the episode number
int i = Integer.valueOf(splittedName[1]);
// returns next episode full name
if (i < 9) {
returnName = splittedName[0] + "E0" + String.valueOf(i + 1);
} else {
returnName = splittedName[0] + "E" + String.valueOf(i + 1);
}
}
}
return returnName;

Related

finding number of words present in the string in java using recursion

A class words defines a recursive function to perform string related operations. The class details
are given below:
Class name : words
Data members/instance variables
text : to store string.
w : integer variable to store total words.
Member functions/methods
words( ) : constructor to store blank to string and 0 to integer data.
void Accept( ) : to read a sentence in text. Note that the sentence may contain more
than one blank space between words.
int FindWords(int) : to count total number of words present in text using Recursive
Technique and store in ‘w’ and return.
void Result( ) : to display the original string. Print total number of words stored in
‘w’ by invoking the recursive function.
I tried this code
public static int CountWords(String str) {
int c = 0;
int i = str.indexOf(" ");
if (str.isEmpty()) {
return 0;
}else
if (i == str.indexOf(" ")) {
return c++;
}
//str.substring(0,str.indexOf(" ")-1);
c++;
return c + CountWords(str.substring(i + 1));
}
but i need to return an integer value and i am confused with that..
In your code, the last return statement is inaccessible. Reason: you have put an if-else block and have put return in both the cases. So the function actually gets returned from the if-else block itself (within else, the condition of if is always true since you assigned the very value i.e. str.indexOf(" ")).
I have written down the code according to the question you gave above...
public int findWords(int i){
if(i > text.lastIndexOf(" "))
return 1;
i = text.substring(i).indexOf(" ") + i;
if(i < 0)
return 1;
if(text.substring(i).equals(null))
return 0;
return( findWords(i+1) + 1);
}
Hope you find it well working.
Your function already is returning a integer, it just happens to always be 0.
This is due to
else if (i == str.indexOf(" ")) {
return c++;
}
Always being true and c++ only updating after the return statement was passed.
This happens because you already set i to be the indexOf(" ") and due to the implementation of incrementation using int++. Also, keep in mind hat you need to increase the number of words by 2 here, since you're ending the function between two words.
Therefore, use this instead:
else if (i == str.lastIndexOf(" ")) {
return c+2;
}
You should see that now the function is returning the correct amount of words.

Check if any part of a string input is not a number

I couldnt find an answer for this in Java, so I'll ask here. I need to check if 3 parts of a string input contains a number (int).
The input will be HOURS:MINUTES:SECONDS (E.g. 10:40:50, which will be 10 hours, 40 minutes and 50 seconds). So far I am getting the values in String[] into an array by splitting it on :. I have parsed the strings into ints and I am using an if statement to check if all 3 parts is equal or larger than 0. The problem is that if I now use letters I will only just get an error, but I want to check if any of the 3 parts contains a character that is not 0-9, but dont know how.
First I thought something like this could work, but really dont.
String[] inputString = input.split(":");
if(inputString.length == 3) {
String[] alphabet = {"a","b","c"};
if(ArrayUtils.contains(alphabet,input)){
gives error message
}
int hoursInt = Integer.parseInt(inputString[0]);
int minutesInt = Integer.parseInt(inputString[1]);
int secondsInt = Integer.parseInt(inputString[2]);
else if(hoursInt >= 0 || minutesInt >= 0 || secondsInt >= 0) {
successfull
}
else {
gives error message
}
else {
gives error message
}
In the end I just want to check if any of the three parts contains a character, and if it doesnt, run something.
If you are sure you always have to parse a String of the form/pattern HH:mm:ss
(describing a time of day),
you can try to parse it to a LocalTime, which will only work if the parts HH, mm and ss are actually valid integers and valid time values.
Do it like this and maybe catch an Exception for a wrong input String:
public static void main(String[] arguments) {
String input = "10:40:50";
String wrongInput = "ab:cd:ef";
LocalTime time = LocalTime.parse(input);
System.out.println(time.format(DateTimeFormatter.ISO_LOCAL_TIME));
try {
LocalTime t = LocalTime.parse(wrongInput);
} catch (DateTimeParseException dtpE) {
System.err.println("Input not parseable...");
dtpE.printStackTrace();
}
}
The output of this minimal example is
10:40:50
Input not parseable...
java.time.format.DateTimeParseException: Text 'ab:cd:ef' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalTime.parse(LocalTime.java:441)
at java.time.LocalTime.parse(LocalTime.java:426)
at de.os.prodefacto.StackoverflowDemo.main(StackoverflowDemo.java:120)
I would personally create my own helper methods for this, instead of using an external library such as Apache (unless you already plan on using the library elsewhere in the project).
Here is an example of what it could look like:
public static void main(String[] arguments) {
String time = "10:50:45";
String [] arr = time.split(":");
if (containsNumbers(arr)) {
System.out.println("Time contained a number!");
}
//You can put an else if you want something to happen when it is not a number
}
private static boolean containsNumbers(String[] arr) {
for (String s : arr) {
if (!isNumeric(s)) {
return false;
}
}
return true;
}
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(.\\d+)?");
}
containsNumbers will take a String array as an input and use an enhanced for loop to iterate through all the String values, using the other helper method isNumeric that checks if the String is a number or not using regex.
This code has the benefit of not being dependent on Exceptions to handle any of the logic.
You can also modify this code to use a String as a parameter instead of an array, and let it handle the split inside of the method instead of outside.
Note that typically there are better ways to work with date and time, but I thought I would answer your literal question.
Example Runs:
String time = "sd:fe:gbdf";
returns false
String time = "as:12:sda";
returns false
String time = "10:50:45";
returns true
You can check the stream of characters.
If the filter does not detect a non-digit, return "Numeric"
Otherwise, return "Not Numeric"
String str = "922029202s9202920290220";
String result = str.chars()
.filter(c -> !Character.isDigit(c))
.findFirst().isEmpty() ? "Numeric"
: "Not Numeric";
System.out.println(result);
If you want to check with nested loop you can see this proposal:
Scanner scanner = new Scanner(System.in);
String [] inputString = scanner.nextLine().split(":");
for (int i = 0; i < inputString.length; i++) {
String current = inputString[i];
for (int k = 0; k < current.length(); k++) {
if (!Character.isDigit(current.charAt(k))) {
System.out.println("Error");
break;
}
}
}
you could use String.matches method :
String notANum= "ok";
String aNum= "7";
if(notANum.matches("^[0-9]+$") sop("no way!");
if(aNum.matches("^[0-9]+$") sop("yes of course!");
The code above would print :
yes of course
The method accepts a regex, the one in the above exemple is for integers.
EDIT
I would use this instead :
if(input.matches("^\d+:\d+:\d+$")) success;
else error
You don't have to split the string.
I tried to make your code better, take a look. You can use Java regex to validate numbers. also defined range for time so no 24:61:61 values is allowed.
public class Regex {
static boolean range(int timeval,int min,int max)
{
boolean status=false;
if(timeval>=min && timeval<max)
{status=true;}
return status;
}
public static void main(String[] args) {
String regex = "[0-9]{1,2}";
String input ="23:59:59";
String msg="please enter valid time ";
String[] inputString = input.split(":");
if(inputString[0].matches(regex) && inputString[1].matches(regex) && inputString[2].matches(regex) )
{
if(Regex.range(Integer.parseInt(inputString[0]), 00, 24) &&Regex.range(Integer.parseInt(inputString[1]), 00, 60) && Regex.range(Integer.parseInt(inputString[2]), 00, 60))
{msg="converted time = " + Integer.parseInt(inputString[0]) + " : " +Integer.parseInt(inputString[1])+ " : " +Integer.parseInt(inputString[2]) ;}
}
System.out.println(msg);
}
}

Join path that overlaps

In java, I have a string that looks like :
"c:\abc\def\ghi"
and another that is
"def\ghi\jkl.txt"
How can I do the intersection of both to have
"c:\abc\def\ghi\jkl.txt"
edit :
The rules are :
replace the maximum of the end of the first string with the maximum of the beginning of the second string.
For example with
b\a\n\a\n\a and a\n\a\n\a\s the result should be b\a\n\a\n\a\s
with "c:\abc\def\ghi" joined to "def\gji\jkl.txt", we have "c:\abc\def\ghi\def\gji\jkl.txt"
I would simply look at the first string and check if it ends with the largest possible beginning of the second string. To be a little bit faster I check on every existing backslash:
public static String join(String begin, String end) {
for (int i = end.lastIndexOf("\\"); i >= 0; i = end.lastIndexOf("\\", i - 1)) {
if (begin.endsWith(end.substring(0, i)) && begin.charAt(begin.length() - (i+1)) == '\\') {
return begin + end.substring(i);
}
}
return "strings dont contain same folder sequence";
}

linear search Arrays check values

I need to get inputs to fill an array. My problem is I also need to check if the value I input does not exist already in the array. If exists I need to show a message that says bad grade. I believe I get stuck on the search loop I and Im not able no assign the value to the array If is not already there.
String[] course = new String[9];
int index = 0;
if (menu == 1) {
boolean found = true;
do {
value = (JOptionPane.showInputDialog("Enter course " + (index + 1)));
int pos = 0;
while (pos< course.length&& !found) {
if (value == course[index]) {
found = true;
} else {
pos++;
}
} // while
if(found == true) {
course[index] = value;
} else {
course[index]="";
}
if (course[index].equals("")) {
JOptionPane.showMessageDialog(null, "Bad Course Name");
} else{
course[index] = (JOptionPane.showInputDialog("Enter course " + (index + 1)));
}
} while(course[index].equals("")); //last
}
The problem with your implementation is that once found is set to true, you never reset it back to false: it's a one-way street. That is why entering the first duplicate value prevents other non-duplicated values from being entered.
You can fix this by moving the declaration/initialization of found inside your do/while loop. However, a better approach would be defining a helper method that searches the array for you up to the specific position, and returns true if a duplicate is found:
private static boolean isDuplicate(String[] course, int maxIndex, String entry) {
...
}
Now the loop searching for duplicates would be hidden, along with the variable indicating the result. The code becomes more readable, too, because the name of the method tells the reader what happens inside.
Of course, you need to fix your string comparison: your code uses ==, which is not the way it is done in Java.

Making a substring out of a line read from file

So I am trying to read through a .txt file and find all instances of html tags, push opening tags to a stack, and then pop it when I find a closing tag. Right now I am getting String out of bounds exception for the following line:
if(scan.next().startsWith("</", 1))
{
toCompare = scan.next().substring(scan.next().indexOf('<'+2), scan.next().indexOf('>'));
tempString = htmlTag.pop();
if(!tempString.equals(toCompare))
{
isBalanced = false;
}
}
else if(scan.next().startsWith("<"))
{
tempString = scan.next().substring(scan.next().indexOf('<'+1), scan.next().indexOf('>'));
htmlTag.push(tempString);
}
It is telling me that the index of the last letter is -1. The problem I can think of is that all of the scan.next() calls are moving onto the next string. If this is the case, do I need to just write
toCompare = scan.next()
and then so my comparisons?
You have two major problems in your code:
you're calling scan.next() way too much and as you expect, this will move the scanner to the next token. Therefore, the last one will be lost and gone.
.indexOf('<'+2) doesn't return the index of '<' and adds 2 to that position, it will return the index of '>', because you're adding 2 to the int value of char < (60; > has 62). Your problem with index -1 ("It is telling me that the index of the last letter is -1.") comes from this call: .indexOf('<'+1) this looks for char '=' and if your string doesn't contain that, then it will return -1. A call for #substring(int, int) will fail if you pass -1 as the starting position.
I suggest the following two methods to extract the value between '<' and '>':
public String extract(final String str) {
if (str.startsWith("</")) {
return extract(str, 2);
} else if (str.startsWith("<")) {
return extract(str, 1);
}
return str;
}
private String extract(final String str, final int offset) {
return str.substring(str.indexOf('<') + offset, str.lastIndexOf('>'));
}
As you can see, the first method evaluates the correct offset for the second method to cut off either "offset. Mind that I wrote str.indexOf('<') + offset which behaves differently, than your str.indexOf('<' + offset).
To fix your first problem, store the result of scan.next() and replace all occurrences with that temporary string:
final String token = scan.next();
if (token.startsWith("</")) { // removed the second argument
final String currentTag = extract(token); // renamed variable
final String lastTag = htmlTag.pop(); // introduced a new temporary variable
if (!lastTag.equals(currentTag)) {
isBalanced = false;
}
}
else if (token.startsWith("<")) {
htmlTag.push(extract(token)); // no need for a variable here
}
I guess this should help you to fix your problems. You can also improve that code a little bit more, for example try to avoid calling #startsWith("</") and #startsWith("<") twice.

Categories

Resources