0

I want to split the string and assign the tokens to different fields, if the tokens size is not as expected it is throwing the ArrayIndexOutOfBoundsException. When the data is as expected, it is showing the empty value.

Sample code:

public class Test {
    public static void main(final String[] args) {
         List<String> firstNames = new ArrayList<>();
         List<String> lastNames = new ArrayList<>();
         List<String> useCaseIds = new ArrayList<>();
         List<String> partner = new ArrayList<>();
         List<String> comments = new ArrayList<>();

         String s = "Annie-Marie--Joe"; // -NoData";
        // final String s = "Annie-Marie-83B782-Joe-NoData"; //showing empty value when printing the list.
         String[] tokens = s.split("-");

        switch (tokens.length) {
        case 1:
            firstNames.add(tokens[0]);
        case 2:
            lastNames.add(tokens[1]);
        case 3:
            useCaseIds.add(tokens[2]);
        case 4:
            partner.add(tokens[3]);
        case 5:
            comments.add(tokens[4]);
        default:
            break;
        }

        System.out.println("firstNames " + firstNames);
        System.out.println("lastNames " + lastNames);
        System.out.println("useCaseIds " + useCaseIds);
        System.out.println("partner " + partner);
        System.out.println("comments " + comments);
    }

}

Output:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4

--EDIT-- Modified the code as shown below.

final String s = "Annie-Marie-83B782-Joe"; // showing empty value when
// printing the list.
final String[] tokens = s.split("-");

switch (tokens.length) {
case 1:
    firstNames.add(tokens[0]);
    break;
case 2:
    lastNames.add(tokens[1]);
    break;
case 3:
    useCaseIds.add(tokens[2]);
    break;
case 4:
    partner.add(tokens[3]);
    break;
case 5:
    comments.add(tokens[4]);
    break;
default:
    break;
}

System.out.println("firstNames " + firstNames);
System.out.println("lastNames " + lastNames);
System.out.println("useCaseIds " + useCaseIds);
System.out.println("partner " + partner);
System.out.println("comments " + comments);

}

Output:

firstNames []
lastNames []
useCaseIds []
partner [Joe]
comments []

Why the firstNames,lastNames,..are blank in my above scenario.

user222
  • 587
  • 3
  • 10
  • 31

3 Answers3

1

It is because your array tokens has only 4 elements. Therefore accessing tokens[4] is causingArrayIndexOutOfBoundsException.

You might wonder how this statement even executed. It is because if you satisfy a switch case and if that switch case do not have break statement, it will execute the below statement as well.

System.out.println(Arrays.toString(tokens));

[Annie, Marie, , Joe]

use break statement inside your cases.

Why the firstNames,lastNames,..are blank in my above scenario.

I think you do not understand how the switch constructs works. Switch will execute only one case where your given parameter is satisfied (Unless you forget to break)

All you have to do is, reverse the switch statement so that depending on the number of tokens, your Lists will be fulfilled.

 switch (tokens.length) {
    case 5:
        comments.add(tokens[4]);                
    case 4:
        partner.add(tokens[3]);             
    case 3:
        useCaseIds.add(tokens[2]);
    case 2:
        lastNames.add(tokens[1]);
    case 1:
        firstNames.add(tokens[0]);
    default:
        break;
 }
Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
1

You have to use a different order in your tricky switch statement:

import java.util.List;
import java.util.ArrayList;
public class Test {
    public static void main(final String[] args) {
         List<String> firstNames = new ArrayList<>();
         List<String> lastNames = new ArrayList<>();
         List<String> useCaseIds = new ArrayList<>();
         List<String> partner = new ArrayList<>();
         List<String> comments = new ArrayList<>();

         //String s = "Annie-Marie--Joe"; // -NoData";
         final String s = "Annie-Marie-83B782-Joe-NoData"; //showing empty value when printing the list.
         String[] tokens = s.split("-");

        switch (tokens.length) {
        case 5:
            comments.add(tokens[4]);                
        case 4:
            partner.add(tokens[3]);             
        case 3:
            useCaseIds.add(tokens[2]);
        case 2:
            lastNames.add(tokens[1]);
        case 1:
            firstNames.add(tokens[0]);
        default:
            break;
        }

        System.out.println("firstNames " + firstNames);
        System.out.println("lastNames " + lastNames);
        System.out.println("useCaseIds " + useCaseIds);
        System.out.println("partner " + partner);
        System.out.println("comments " + comments);
    }

}

Tested on jdoodle

Adder
  • 5,708
  • 1
  • 28
  • 56
  • thanks.Is there any better way to implement this kind of logic instead of using switch statements. – user222 Sep 13 '19 at 15:10
  • Not really, you could use multiple `if`s. I think using the `switch` with omitting the `break;` is a nice trick, though hard to understand for some. – Adder Sep 13 '19 at 15:13
  • 1
    @user222 I think you should create a `User` object if you plan on importing multiple strings `s` instead of having 5 separate lists. The reason is that if one match is missing data e.g. the comments then the 5 lists get out of sync. – Adder Sep 13 '19 at 15:26
1

You ask if there is a better solution than switch with tricky drop-throughs. How about this?

The switch is replaced with a loop, and we get around the variable names problem by making an array of the lists.

import java.util.List;
import java.util.ArrayList;
public class Test {
    public static void main(final String[] args) {
        List<String> firstNames = new ArrayList<>();
        List<String> lastNames = new ArrayList<>();
        List<String> useCaseIds = new ArrayList<>();
        List<String> partner = new ArrayList<>();
        List<String> comments = new ArrayList<>();

        List<String>[] lists = new List<String>[]{
            firstNames, lastNames, useCaseIds, partner, comments
        };

        // String s = "Annie-Marie--Joe";
        String s = "Annie-Marie-83B782-Joe-NoData";

        String[] tokens = s.split("-");

        for (int i = 0; i < Math.min(lists.length, tokens.length); i++) {
             lists[i].add(tokens[i]);
        }

        System.out.println("firstNames " + firstNames);
        System.out.println("lastNames " + lastNames);
        System.out.println("useCaseIds " + useCaseIds);
        System.out.println("partner " + partner);
        System.out.println("comments " + comments);
    }
}

Having said this, what you are doing here is not good OO design. What you should do is create a Person class to represent the information in a line in your input file. Then replace the 5 separate lists of strings with a single List<Person>.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216