-3

I was wondering how to ignore spaces in Java. This program allows you to enter your first, middle and surname which then outputs your initials. I'm now trying to make it ignore any white spaces. Thanks in advance!

        String fullName;
        char firstName;
        char secondName;
        char surname;
        int space1;
        int space2;
                
        System.out.println("Please enter your first name, your second name and your surname: ");
        fullName = kybd.nextLine();
          
        firstName = fullName.charAt(0);
        space1 = fullName.indexOf(" ");
        secondName = fullName.charAt(space1 + 1);
        space2 = fullName.lastIndexOf(" ");
        surname = fullName.charAt(space2 + 1);
            
        System.out.println("Initials: " + firstName + secondName + surname);
invzbl3
  • 5,872
  • 9
  • 36
  • 76
Smithy98
  • 11
  • 1
  • 1
  • 2
  • 2
    Just remove all whitespaces inside `fullName`. For example by `fullName.replaceAll(" ", "")`. – Zabuzard Nov 11 '17 at 22:39
  • Currently your question is a bit unclear. Can you give some example inputs and expected outputs? – Zabuzard Nov 11 '17 at 22:41
  • Please consider **accepting** an answer if it solved your issue. That helps SO filtering answered from unanswered questions, thanks. – Zabuzard Nov 11 '17 at 23:24

2 Answers2

3

Explanation

You can implicitly ignore them by just removing them from your input text.

Therefore replace all occurrences with "" (empty text):

fullName = fullName.replaceAll(" ", "");

After that call fullName won't contain a whitespace anymore.

However you'll then get a problem with your logic as you split on whitespaces.


Solution

An alternative could be to first trim the text (removing leading and trailing whitespaces). Then do your split and after that you can remove all other whitespaces:

fullName = kybd.nextLine();
// Remove leading and trailing whitespaces
fullName = fullName.trim();

// Bounds
firstSpace = fullName.indexOf(" ");
lastSpace = fullName.lastIndexOf(" ");

// Extract names
String fullFirstName = fullName.substring(0, firstSpace);
String fullSecondName = fullName.substring(firstSpace + 1, lastSpace);
String fullSurname = fullName.substring(lastSpace + 1);

// Trim everything
fullFirstName = fullFirstName.trim(); // Not needed
fullSecondName = fullSecondName.trim();
fullSurname = fullSurname.trim();

// Get initials
firstName = fullFirstName.charAt(0);
secondName = fullSecondName.charAt(0);
surname = fullSurname.charAt(0);

Example

Let's take a look at an example input (_ stands for whitespace):

__John___Richard_Doe_____

We will first trim fullName and thus get:

John___Richard_Doe

Now we identify the first and the last whitespace and split on them:

First name:  John
Second name: ___Richard
Surname:     _Doe

Last we also trim everything and get:

First name:  John
Second name: Richard
Surname:     Doe

With charAt(0) we access the initials:

First name:  J
Second name: R
Surname:     D

More dynamic

Another more dynamic approach would be to merge all successive whitespaces into a single whitespace. Therefore you would need to traverse the text from left to right and start recording once you see a whitespace, end recording if visiting a non-whitespace character, then replace that section by a single whitespace.

Our example then is:

_John_Richard_Doe_

And after an additional trim you can use your regular approach again:

John_Richard_Doe

Or you can use split(" ") and then reject every empty String:

Iterator<String> elements = Pattern.compile(" ").splitAsStream(fullName)
    .filter(e -> !e.isEmpty())     // Reject empty elements
    .collect(Collectors.toList())  // Collect to list
    .iterator()                    // Iterator

firstName = elements.next().charAt(0);
secondName = elements.next().charAt(0);
surname = elements.next().charAt(0);

Using the example again the Stream first consists of

"", "", "John", "", "", "Richard", "Doe", "", "", "", "", ""

after the filtering it's

"John", "Richard", "Doe"

Minus Sign

As you said you also want

Richard Jack Smith-Adams

output RJS-A, you can simply split on - after splitting on the whitespace.

Pattern spacePatt = Pattern.compile(" ");
Pattern minusPatt = Pattern.compile("-");
String result = spacePatt.splitAsStream(fullName)  // Split on " "
    .filter(e -> !e.isEmpty())                     // Reject empty elements
    .map(minusPatt::splitAsStream)                 // Split on "-"
    .map(stream ->
        stream.map(e -> e.substring(0, 1)))        // Get initials
    .map(stream ->
        stream.collect(Collectors.joining("-")))   // Add "-"
    .collect(Collectors.joining(""));              // Concatenate

Which outputs RJS-A.

This approach is a bit more complicated as we need to maintain the information of the sub-streams, we can't just flatMap everything together, otherwise we wouldn't know where to add the - again. So in the middle part we are indeed operating on Stream<Stream<String>> objects.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • I'm unsure where to put that code, can you please tell me? – Smithy98 Nov 11 '17 at 22:50
  • @Smithy98 Yeah, I edited the code, is it clearer now? – Zabuzard Nov 11 '17 at 22:59
  • It does make sense but I get errors for the 2 lines of code under "Bounds". It says "possible lossy conversion from int to char". I've declared them as chars, not an int though.. – Smithy98 Nov 11 '17 at 23:01
  • @Smithy98 Oh, yeah they should be `int` **not** `char`. The method returns the **position** at which this character occurs, not a **character**. – Zabuzard Nov 11 '17 at 23:04
  • Of course! Thanks so much for the help, it works now. I really appreciate it! – Smithy98 Nov 11 '17 at 23:17
  • @Smithy98 You're welcome! I've edited the answer again, check out the last example using `Stream`s, I really like it, it's also very compact. – Zabuzard Nov 11 '17 at 23:23
  • Thanks. I also want it to include hyphenated names, e.g. Smith-Adams. How would I go about doing this? – Smithy98 Nov 11 '17 at 23:27
  • @Smithy98 So you want to treat `Smith-Adams` as `Smith Adams`? Just replace every such character before with a *whitespace*: `fullName = fullName.replaceAll("-", " ")`. You can also use **regex** here to include more than just `-`, just as reference. – Zabuzard Nov 11 '17 at 23:32
  • No, sorry, I want it to include both of the hyphenated names as one initial. For example, if I entered Richard Jack Smith-Adams, it would be displayed as RJS-A – Smithy98 Nov 11 '17 at 23:38
  • @Smithy98 Mh.. Before picking the initial of `fullXYName` you can then simply do the same procedure with `-`, just split on it. I've edited the answer by adding a `Stream` version again. – Zabuzard Nov 12 '17 at 14:09
0

I think what you're after here is the split method in String

Which you could use like this:

String fullName = "John Alexander Macdonald";
String[] split = fullName.split(" "); // ["John", "Alexander", "Macdonald"]

The other thing you might want is the trim method which removes spaces from the front and the back of a string.

String withSpaces = " a b c ";
String trimmed = withSpace.trim(); // "a b c"