1

Let's say I have a String (call it s) with the following format:

[String] [String] [double] [int]

for example, "YES james 3.5 2" I would like to read this data into separate variables (a String, a String, a double, and an int)

Note that I come from a C++ background. In C++, I would do something like the following:

std::istringstream iss{s};   // create a stream to the string

std::string first, second; 
double third = 0.0;
int fourth = 0;
iss >> first >> second >> third >> fourth;  // read data

In Java, I came up with the following code:

String[] sa = s.split(" ");
        
String first = sa[0], second = sa[1];
double third = Double.parseDouble(sa[2]);
int fourth = Integer.parseInt(sa[3]);

However, I will have to do this to many different inputs, so I would like to use the most efficient and fastest way of doing this.

Questions:

  • Is there any more efficient/faster way of doing this? Perhaps a cleaner way?
Captain Hatteras
  • 490
  • 3
  • 11
  • What do you plan on doing with these? If you just need to get these as Strings you could use Arrays.asList(s.split(" ")); which would leave you with a list of Strings. Also, you may need to use special regex to split on all spaces, such as s.split("\\s+"); – Cameron Grande Dec 21 '21 at 20:08
  • Do you actually have strings or do you have some other data to read first, like a file or a network data stream? – markspace Dec 21 '21 at 20:09
  • 1
    If you're reading input you could use a Scanner, with `next()`, `nextInt()` etc. – khelwood Dec 21 '21 at 20:15
  • @CameronGrande I need these as their actual type, i.e., String, String, double, int. – Captain Hatteras Dec 21 '21 at 20:17
  • @markspace Yes, I am working with strings. I am not the one in control of where I am getting them from. – Captain Hatteras Dec 21 '21 at 20:17
  • 1
    C(+) is so elegant! :) ...but java so typesafe! :-))^^ Generally in java/on large scale (in c surely also more efficient) I would recommend with regex! But when you say "many different inputs" ..i think of more structured (csv/json/fixed width, library-based) solution – xerx593 Dec 21 '21 at 20:18
  • @khelwood see my comment to markspace. – Captain Hatteras Dec 21 '21 at 20:18
  • 2
    [Scanner](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Scanner.html) can take a `String` as input. – Kayaman Dec 21 '21 at 20:24
  • @Kayaman Interesting! Thank you! – Captain Hatteras Dec 21 '21 at 20:24
  • 1
    [see also (split() vs Scanner vs Tokenizer)](https://stackoverflow.com/q/691184/592355) – xerx593 Dec 21 '21 at 20:49
  • 1
    +1 for: ["One important difference is that both String.split() and Scanner can produce empty strings but StringTokenizer never does it."](https://stackoverflow.com/a/36775514/592355) – xerx593 Dec 21 '21 at 20:51

2 Answers2

1

As it has been mentioned in the comments, if this is coming from keyboard (or really from an input stream) you could use Scanner class to do so. However, from input sources other than keyboard, I will not use Scanner but some other method to parse strings. For example, if reading lines from a file, you may want to use a Reader instead. For this answer, I will assume the input source is the keyboard.

Using Scanner to get the input

Scanner scanner = new Scanner(System.in);
System.out.print("Provide your input: ");
String input = scanner.nextLine();
input.close();

Break the String into tokens

Here you have a few options. One is to break down the string into substring by splitting the input using white space as a delimeter:

String[] words = input.split("\\s");

If the order of these substrings is guaranteed, you can assign them directly to the variables (not the most elegant solution - but readable)

String first = words[0];
String second = words[1];
double third = words[2];
int fourth = words[3];

Alternatively, you can extract the substrings directly by using String#substring(int) and/or String#substring(int, int) methods and test whether or not the obtained substring is a number (double or int), or just simply a string.

hfontanez
  • 5,774
  • 2
  • 25
  • 37
1

Try it like this. Scanner's constructor can take a string as a data source.

Scanner scan = new Scanner("12 34 55 88");
while (scan.hasNext()) {
   System.out.println(scan.nextInt());  
}

prints

12
34
55
88
WJS
  • 36,363
  • 4
  • 24
  • 39