I am noticing strange behaviour when using the split() method in Java.
I have a string as follows: 0|1|2|3|4|5|6|7|8|9|10
String currentString[] = br.readLine().split("\\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This will produce the desired results:
Length: 11
0
1
2
3
4
5
6
7
8
9
10
However if I receive the string: 0|1|2|3|4|5|6|7|8||
I get the following results:
Length: 8
0
1
2
3
4
5
6
7
8
The final 2 empties are omitted. I need the empties to be kept. Not sure what i am doing wrong. I have also tried using the split in this manner as well. ...split("\\|",-1);
but that returns the entire string with a length of 1.
Any help would be greatly appreciated!
The default behavior of split is to not return empty tokens (because of a zero limit). Use the two parameter split method with a limit of -1 will give you all empty tokens in the return.
UPDATE:
Test code as follows:
public class Test {
public static void main(String[] args) {
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|", -1);
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){ System.out.println(currentString[i]); }
}
}
Output as follows:
Length:11
0
1
2
3
4
5
6
7
8
--- BLANK LINE --
--- BLANK LINE --
The "--- BLANK LINE --" is put in by me to show that the return is blank. It is blank once for the empty token after 8| and once for the empty trailing token after the last |.
Hope this clears things up.
String.split() is weird.
Its extreme weirdness, in this and other ways, are some of the reasons why we made Splitter.
It has less surprising behavior and lots of flexibility.
My Java is a little bit rusty, but shouldn't it be:
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|");
System.out.println("Length:"+currentString.length);
for(int i = 0; i < currentString.length; i++)
{
System.out.println(currentString[i]);
}
IMO, I think this is the default behavior of split, Anyway please try this:
String currentString[] = br.readLine().replace("||","| |").split("\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This has not been tested yet, but i think this should do the trick.
You need to use indexOf() and then substring() for this to work. I don't think you can empty string by using split() only.
Please check the following code, I used your solution, it works:
public class SplitTest
{
public static void main(String[] args)
{
String text = "0|1|2|3|4|5|6|7|8||";
String pattern = "\\|";
String [] array = text.split(pattern, -1);
System.out.println("array length:" + array.length);
for(int i=0; i< array.length; i++)
System.out.print(array[i]+ " ");
}
}
output is:
array length:11
0 1 2 3 4 5 6 7 8
Related
I am quite new to java. I am wondering if it is possible to check for a certain number of consecutively repeated characters (the 'certain number' being determined by the user) in a string or an index in a string array. So far I have tried
int multiple_characters = 0;
String array1 [] = {"abc","aabc","xyyyxy"};
for (int index = 0; index < array1.length;i++){
for (int i = 0;i<array1[index].length;i++){
if (array1[index].charAt(i) == array1[index].charAt(i+1)){
multiple_characters++;
}
}
}
But with this I get a StringIndexOutOfBounds error. I tried fixing this by putting in an extra if statement to make sure i was not equal to the array1[index].length, but this still threw up the same error. Other than the manual and cop-out method of:
if ((array1[index].charAt(i) == array1[index].charAt(i+1) && (array1[index].charAt(i) == array1[index].charAt(i+2))
and repeating however many times, (which would not be great for quick changes to my code), I can't seem to find a solution.
For the inner for loop (the one with the i variable), you're then calling string.charAt(i+1) where ii loops from 0 to the length of that string.
No wonder you get an index array out of bounds exception, you're asking for the character AFTER the last.
I advise that you try to understand the exception, and if you can't, debug your code (step through it, one line at a time, and if you don't know how to use a debugger, add println statements, checking what the code does what with you think it does. There where your code acts differently from your expectation? That's where the bug is).
This plan of 'oh, it does not work, I'll just chuck it out entirely and find another way to do it' is suboptimal :) – go back to the first snippet, and just fix this.
You are getting StringIndexOutOfBoundsException because you are trying to access string.charAt(i + 1) where i goes up to the highest index (i.e. string.length() - 1) of string.
You can do it as follows:
class Main {
public static void main(String[] args) {
int multiple_characters = 0;
int i;
String array1[] = { "abc", "aabc", "xyyyxy" };
for (int index = 0; index < array1.length; index++) {
System.out.println("String: " + array1[index]);
for (i = 0; i < array1[index].length() - 1; i++) {
multiple_characters = 1;
while (array1[index].charAt(i) == array1[index].charAt(i + 1) && i < array1[index].length() - 1) {
multiple_characters++;
i++;
}
System.out.println(array1[index].charAt(i) + " has been repeated consecutively " + multiple_characters
+ " time(s)");
}
if (multiple_characters == 1) {
System.out.println(array1[index].charAt(i) + " has been repeated consecutively 1 time(s)");
}
System.out.println("------------");
}
}
}
Output:
String: abc
a has been repeated consecutively 1 time(s)
b has been repeated consecutively 1 time(s)
c has been repeated consecutively 1 time(s)
------------
String: aabc
a has been repeated consecutively 2 time(s)
b has been repeated consecutively 1 time(s)
c has been repeated consecutively 1 time(s)
------------
String: xyyyxy
x has been repeated consecutively 1 time(s)
y has been repeated consecutively 3 time(s)
x has been repeated consecutively 1 time(s)
y has been repeated consecutively 1 time(s)
------------
If I was to look for repeated characters, I would go the regular expression route. For example to look for repeated a characters (repeated twice in this example), you could have:
import java.util.regex.Pattern;
public class Temp {
public static void main(final String[] args) {
String array1 [] = {"abc","aabc","xyyyxy"};
for (String item : array1){
if (Pattern.compile("[a]{2}").matcher(item).find()) {
System.out.println(item + " matches");
}
}
}
}
In this extract, the reg exp is "[a]{2}" which looks for any sequence of a characters repeated twice.
Of course more complicated regular expressions are required for more complex matches, good resources to explain this may be found here:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html
Another point is that for efficiencies sake, it is often practise to move the:
Pattern.compile(*Pattern*)
outside of the method call, e.g. to a final static field
This stack overflow:
RegEx No more than 2 identical consecutive characters and a-Z and 0-9
gives quite a detailed description of the regular expression issues involved with this problem.
I think I've gotten mostly to a solution for a homework problem.
This is for a 201 CS class. Right now I just want to get the logic right. At present, it doesn't operate as intended, but it's close.
We don't want to use .toBinary, bitwise, or anything else. We also haven't been taught stringBuilder, so I'd like to avoid using it.
There's a System.out.println(); within the method which provides the correct answer if you read the console from bottom to top.
public static void main(String[] args) {
System.out.println(addBin(1100111011,1101110011));
}
public static String addBin(int num1,int num2){
String result = "";
if(num1 > 0 || num2 > 0){
int part1 = num1%10, part2 = num2%10;
int rem1 = num1/10, rem2 = num2/10;
result += Integer.toString((part1 + part2)%2);
//System.out.println(result);
int carry = (part1 + part2) /2;
addBin(rem1 + carry, rem2);
return result;
}
return result;
}
So, this example adds 1100111011 and 1101110011 with the output
0
1
1
1
0
1
0
1
0
1
1
0
when the correct answer is 11010101110.
I'm having trouble understanding how to properly "pop" the "result" part properly. Could you please help me understand this process, possibly within the context of this problem?
Thanks!
As you can see from your output, you are getting the correct result in the reverse order but you are not appending any of your older result to the ones that are being currently computed.
Inside your if condition, you are calling the addBin() function but you are not using the result that it gives anywhere. Just change that line to the following:
result = addBin(rem1 + carry, rem2)+result;
That should effective append all your results in front of the current answer so that you do not get the result in backwards direction. Hope this helps.
My requirement is to generate 1000 unique email-ids in Java. I have already generated random Text and using for loop I'm limiting the number of email-ids to be generated. Problem is when I execute 10 email-ids are generated but all are same.
Below is the code and output:
public static void main() {
first fr = new first();
String n = fr.genText()+"#mail.com";
for (int i = 0; i<=9; i++) {
System.out.println(n);
}
}
public String genText() {
String randomText = "abcdefghijklmnopqrstuvwxyz";
int length = 4;
String temp = RandomStringUtils.random(length, randomText);
return temp;
}
and output is:
myqo#mail.com
myqo#mail.com
...
myqo#mail.com
When I execute the same above program I get another set of mail-ids. Example: instead of 'myqo' it will be 'bfta'. But my requirement is to generate different unique ids.
For Example:
myqo#mail.com
bfta#mail.com
kjuy#mail.com
Put your String initialization in the for statement:
for (int i = 0; i<=9; i++) {
String n = fr.genText()+"#mail.com";
System.out.println(n);
}
I would like to rewrite your method a little bit:
public String generateEmail(String domain, int length) {
return RandomStringUtils.random(length, "abcdefghijklmnopqrstuvwxyz") + "#" + domain;
}
And it would be possible to call like:
generateEmail("gmail.com", 4);
As I understood, you want to generate unique 1000 emails, then you would be able to do this in a convenient way by Stream API:
Stream.generate(() -> generateEmail("gmail.com", 4))
.limit(1000)
.collect(Collectors.toSet())
But the problem still exists. I purposely collected a Stream<String> to a Set<String> (which removes duplicates) to find out its size(). As you may see, the size is not always equals 1000
999
1000
997
that means your algorithm returns duplicated values even for such small range.
Therefore, you'd better research already written email generators for Java or improve your own (for example, by adding numbers, some special characters that, in turn, will generate a plenty of exceptions).
If you are planning to use MockNeat, the feature for implementing email strings is already implemented.
Example 1:
String corpEmail = mock.emails().domain("startup.io").val();
// Possible Output: tiptoplunge#startup.io
Example 2:
String domsEmail = mock.emails().domains("abc.com", "corp.org").val();
// Possible Output: funjulius#corp.org
Note: mock is the default "mocking" object.
To guarantee uniqueness you could use a counter as part of the email address:
myqo0000#mail.com
bfta0001#mail.com
kjuy0002#mail.com
If you want to stick to letters only then convert the counter to base 26 representation using 'a' to 'z' as the digits.
I am trying to compare to strings by using an algorithm as you see below
My code does not work .. eclipse does not show any error before I run the code
public class MysteryClass {
public static void mystery(String n) {
String k= "alla";
if (k.charAt(k.length())==n.charAt(n.length())) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");
}
}
public static void main(String[] args) {
MysteryClass.mystery("alla");
}
}
but we I run the code I get
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:658)
at shapes.MysteryClass.mystery(MysteryClass.java:6)
at shapes.MysteryClass.main(MysteryClass.java:15)
How to fix that??
thanks
Not sure what you want, but your StringIndexOutOfBoundsException is cause by access an array's index which is does not exist.
Take your String k = "alla" as example, k.length() will return 4 because "alla" have four characters, and you are accessing k.charAt(4), the "alla"break into as follows:
a l l a // string
0 1 2 3 // index
As you can see the last index of "alla" is 3, that's why you get StringIndexOutOfBoundsException. But you can solve it using .length() -1 as follow:
if (k.charAt(k.length()-1)==n.charAt(n.length()-1)) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");
Alternative:
If you want to compare two string, you can use .equals method too, as follow:
if (k.equals(n)) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");
Two issues with your code:-
1)By your logic, tigert is also palindrome but it is actually not.Palindrome is when the word is completely reversed and it is still the same.Currently,you are checking only the first and last character
2)String is internally held as a char array and arrays have indexing from 0 to length -1
The error is caused by the statement if (k.charAt(k.length())==n.charAt(n.length()))
Above k.length() returns 4. the statement then resolves to:
(k.charAt(4)
This will through error because the function charAt counts from the index 0. So it counts the characters at index 0, 1, 2, 3 and you are asking it to fetch character at index 4 which does not exist.
A suggested alternative is :
(k.charAt(k.length() -1)==n.charAt(n.length()-1))
I made a program that should output 2 lists of strings (anywhere between 2 and 5) at the end of the line, I want to print an int in brackets.
I am having trouble right justifying the int and the brackets.
All of the printf formatting does not help with moving the int and its surrounding brackets!
while (dealerPoints < 17 && playerBust == false) {
System.out.printf("\nDealer has less than 17. He hits...\n");
int nextDealerCard = dealCard();
dealerPoints += cardValue(nextDealerCard);
dealerHand += faceCard(nextDealerCard);
System.out.printf("Dealer: %s\t[%d]\n", dealerHand, dealerPoints);
System.out.printf("Player: %s\t[%d]\n", playerHand, playerPoints);
}
When there are 4 strings on one line and only 2 on the other, the int and brackets don't align with each other (the one after 4 strings, gets tabbed over too far)
System.out.printf("Dealer: %s\t[%10d]\n", "lala", 22222);
System.out.printf("Player: %s\t[%10d]\n", "hoho", 33);
Outputs:
Dealer: lala [ 22222]
Player: hoho [ 33]
is this what you want?
If you want to right justify, you can either
- write the output in a file as a CSV and open it in an excel like program
- create a utility class that will make any input string a constant length:
public static String fixedCharCount( String input, int length ) {
int spacesToAdd = length - input.lengh();
StringBuffer buff = new StringBuffer(input);
for( int i=0; i<spacesToAdd; i++) {
buff.append(" ");
}
return buff.toString();
}
You can also loop on all your data befor display to see what is the longest String in your table and adapt the length to it (the code is not complete: you must check 'spacesToAdd' is positive.