This commit is contained in:
@@ -235,11 +235,226 @@ public class ParseIntExample {
|
||||
public static void main(String[] args) {
|
||||
String s = "123";
|
||||
int sum = 321;
|
||||
//! sum = sum + s;
|
||||
sum = sum + Integer.parseInt(s);
|
||||
System.out.println(sum);
|
||||
//! int result = s + sum;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The commented out line (`//!`) would have given us an exception.
|
||||
|
||||
```bash
|
||||
$ javac ParseIntExample.java
|
||||
ParseIntExample.java:8: error: incompatible types: String cannot be converted to int
|
||||
int result = s + sum;
|
||||
^
|
||||
1 error
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Please note that if we change `result` data type to `String`, the code will work just fine.
|
||||
> ```java
|
||||
> // ParseIntExample.java
|
||||
> public class ParseIntExample {
|
||||
>
|
||||
> public static void main(String[] args) {
|
||||
> String s = "123";
|
||||
> int sum = 321;
|
||||
> String result = s + sum;
|
||||
> System.out.println(result);
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
> ```bash
|
||||
> $ javac ParseIntExample.java && java ParseIntExample
|
||||
> 123321
|
||||
> ```
|
||||
> In this case `sum` will be ***automatically casted*** to `String` and two strings will just concatenate.
|
||||
|
||||
So we figured out that we need to cast `argument` to integer type. Let's change our code and test it.
|
||||
|
||||
```java
|
||||
// Sum.java
|
||||
|
||||
public class Sum {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("number of arguments: " + args.length);
|
||||
|
||||
int sum = 0;
|
||||
for (String argument : args) {
|
||||
sum = sum + Ineteger.parseInt(argument);
|
||||
System.out.println(argument);
|
||||
System.out.println(sum);
|
||||
}
|
||||
|
||||
System.out.println(sum);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// Sum.java
|
||||
|
||||
public class Sum {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("number of arguments: " + args.length);
|
||||
|
||||
int sum = 0;
|
||||
for (String argument : args) {
|
||||
sum = sum + Integer.parseInt(argument);
|
||||
System.out.println(
|
||||
"current argument: " + argument + ", current sum: " + sum
|
||||
);
|
||||
}
|
||||
|
||||
System.out.println("final sum: " + sum);
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
$ java Sum 1 2 3
|
||||
number of arguments: 3
|
||||
current argument: 1, current sum: 1
|
||||
current argument: 2, current sum: 3
|
||||
current argument: 3, current sum: 6
|
||||
final sum: 6
|
||||
```
|
||||
```bash
|
||||
$ java Sum 1 2 -3
|
||||
number of arguments: 3
|
||||
current argument: 1, current sum: 1
|
||||
current argument: 2, current sum: 3
|
||||
current argument: -3, current sum: 0
|
||||
final sum: 0
|
||||
```
|
||||
```bash
|
||||
$ java Sum "1 2 3"
|
||||
number of arguments: 1
|
||||
Exception in thread "main" java.lang.NumberFormatException: For input string: "1 2 3"
|
||||
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
|
||||
at java.base/java.lang.Integer.parseInt(Integer.java:662)
|
||||
at java.base/java.lang.Integer.parseInt(Integer.java:778)
|
||||
at Sum.main(Sum.java:9)
|
||||
```
|
||||
|
||||
As we can see because we have only 1 argument (`"1 2 3"`) we try to parse it as an integer but `"1 2 3"` contains empty spaces, so it can't be parsed as an integer.
|
||||
|
||||
We need to manually extract numeric values from the `argument` string.
|
||||
|
||||
In order to do that we will iterate over each symbol of the `argument` string and extract numeric values.
|
||||
|
||||
We will have another variable `number` of `String` type in which we will be storing extracted numeric values.
|
||||
|
||||
For every character or symbol in the string, we will check it to be an empty space or a digit. If it is a digit, we will add/concatenate with `number`, and if it is an empty space, we will add the numeric value of `number` to `sum` and then assign empty string to `number` because we reached the end of the current number and are ready to move to the next one.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> It is important to add numeric value of `number` (if it's not empty) to `sum` after we iterated over the entire string because if it ends like this `"1 2 3"`, we don't nessesarily have an empty space at the end so `"3"` (in this case) will be stored in `number` but NOT added to `sum`.
|
||||
|
||||
Let's implement those ideas into solution. We will get rid of all the `println` messages so it's not drawing our attention.
|
||||
|
||||
> [!NOTE]
|
||||
> Also I want to point out that we can't just iterate over `String`. First we need to turn it into an ***array of characters*** using [`String.toCharArray()`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#toCharArray--) method.
|
||||
|
||||
> [!NOTE]
|
||||
> We will be checking for an empty space using [`Character.isWhitespace(char ch)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isWhitespace-char-) which outputs `true` or `false` accordingly.
|
||||
|
||||
```java
|
||||
// Sum.java
|
||||
|
||||
public class Sum {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int sum = 0;
|
||||
for (String argument : args) {
|
||||
String number = ""; // we will form numbers here
|
||||
for (char c : argument.toCharArray()) {
|
||||
if (!Character.isWhitespace(c)) {
|
||||
// if character is not whitespace
|
||||
number = number + c; // concatenate new digit
|
||||
} else {
|
||||
// if character is whitespace
|
||||
if (!number.isEmpty()) {
|
||||
// if number is not empty
|
||||
sum = sum + Integer.parseInt(number); // add number to sum
|
||||
}
|
||||
number = ""; // empty the number
|
||||
}
|
||||
}
|
||||
|
||||
// check for any remaining digits in number
|
||||
if (!number.isEmpty()) {
|
||||
// if number is not empty
|
||||
sum = sum + Integer.parseInt(number); // add number to sum
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(sum);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ java Sum 1 2 3
|
||||
6
|
||||
```
|
||||
```bash
|
||||
$ java Sum 1 2 -3
|
||||
0
|
||||
```
|
||||
```bash
|
||||
$ java Sum "1 2 3"
|
||||
6
|
||||
```
|
||||
```bash
|
||||
$ java Sum "1 2" " 3"
|
||||
6
|
||||
```
|
||||
```bash
|
||||
$ java Sum " "
|
||||
0
|
||||
```
|
||||
|
||||
This code works and passes all the tests!
|
||||
|
||||
But can we improve it? One efficiency improvement we can make is to get rid of concatenating strings. You can read why it's bad [here](https://stackoverflow.com/questions/18561424/using-for-strings-in-a-loop-is-it-bad-practice) or [here](https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://www.reddit.com/r/javahelp/comments/19e9jic/question_about_dont_concat_string_in_a_loop/&ved=2ahUKEwiCpva0y-GTAxUeB9sEHbvzHj4QFnoECCAQAQ&usg=AOvVaw3gk39Xk7Jz9_PmKVIO81nK).
|
||||
|
||||
We can use [StringBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html) because it can ***build*** strings more efficiently.
|
||||
|
||||
So here's the updated code
|
||||
|
||||
```java
|
||||
// Sum.java
|
||||
|
||||
public class Sum {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int sum = 0;
|
||||
for (String argument : args) {
|
||||
StringBuilder number = new StringBuilder(); // we will form numbers here using StringBuilder
|
||||
for (char c : argument.toCharArray()) {
|
||||
if (!Character.isWhitespace(c)) {
|
||||
// if character is not whitespace
|
||||
number.append(c); // concatenate new digit
|
||||
} else {
|
||||
// if character is whitespace
|
||||
if (!number.isEmpty()) {
|
||||
// if number is not empty
|
||||
sum = sum + Integer.parseInt(number.toString()); // add number to sum
|
||||
}
|
||||
number = new StringBuilder(); // empty the number by creating new empty StringBuilder
|
||||
}
|
||||
}
|
||||
|
||||
// check for any remaining digits in number
|
||||
if (!number.isEmpty()) {
|
||||
// if number is not empty
|
||||
sum = sum + Integer.parseInt(number.toString()); // add number to sum
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(sum);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Note, that we can't just do `Integer.parseInt()`
|
||||
|
||||
Reference in New Issue
Block a user