Can anyone give me advice on how I can improve my answer? I have tested it out using "ABCA", "BCABA" and "ABC". Two things I would like help on. 1.How can I move this code into a method where it returns the reoccurring char? I know how to return the char once it has been found but what about the case where there is not char what do I return back in that case? Since I cannot return char. 2. Is using the break statement bad practice? I noticed that the code would with "BCABA" both "B" and "A" are printed.
Thanks.
public static void main(String[] args) {
String testString = "BCABA";
Map<Character, Integer> recurringCharsMap = new HashMap<>();
for (char character : testString.toCharArray()) {
if (recurringCharsMap.containsKey(character)) {
System.out.println("Recurring char is: " + character);
break;
} else {
recurringCharsMap.put(character, 1);
}
}
}
3 Answers 3
Having a method with
Character
return type (instead of the primitivechar
) allows you to returnnull
when no recurring character is found.Instead of using
break
, you can return the first recurring character you find. If none are found, returnnull
.You don't need a
HashMap
(unless you want to count the number of occurrences of each character, which you don't). Use aHashSet
instead.public static Character findFirstRecurringChar (String input) { Set<Character> recurringChars = new HashSet<>(); for (char character : input.toCharArray()) { if (!recurringChars.add(character)) { // add will return false if character is // already in the Set return character; // return the first recurring character } } return null; // no recurring characters }
Then you can call the method with:
public static void main (java.lang.String[] args) {
System.out.println (findFirstRecurringChar ("BCABA"));
}
-
1\$\begingroup\$ @Snowbody That's not required in Java 7 and later (Java can infer the parameter type). \$\endgroup\$Eran– Eran2017年12月20日 07:58:47 +00:00Commented Dec 20, 2017 at 7:58
-
\$\begingroup\$ Yep, just saw that in the docs. Time for me to get back up to speed on Java. \$\endgroup\$Snowbody– Snowbody2017年12月20日 08:03:27 +00:00Commented Dec 20, 2017 at 8:03
-
\$\begingroup\$ I think it would be better if ‘!recurringChars.add(character)’ is extracted and placed in a method isRecurring(character, recurringChars) (maybe there is a better name for this) to imrpove the readability of the code. Also, instead of returning null, I think you should return a blank character in case there are no recurring characters. \$\endgroup\$Rocket Pingu– Rocket Pingu2018年01月11日 02:57:22 +00:00Commented Jan 11, 2018 at 2:57
The Character
type already has everything you need. It is either a character or the special value null
.
For this task you don't need a map, a simple set is enough.
When you move this code into a separate method, using break
becomes bad style because you should directly return
. In the currect code it's ok.
public static Character findFirstRecurring(String str, char ch) {
// Left as an exercise
...
return null;
}
String
s in Java are Unicode, stored as UTF-16. This means that Unicode code points from the BMP (U+0000 to U+FFFF) are represented as one char
, but Unicode code points from the SMP (U+10000 to U+10FFFF) are represented as a pair of char
s from special ranges. For instance, Chinese characters. So if you just look at individual char
you may get bad results if there is more than one SMP code point in the string (and if an SMP code point is the one repeated, you'll return a completely wrong value). The proper way to do this is to look at code points.
I'm basing off of Eran's answer.
public static int findFirstRecurringCodePoint (String input) {
Set<Integer> usedCodePoints = new HashSet<>(); // int representing a Unicode code point
for (int i=0; i<input.length(); i++) {
int codePoint = input.codePointAt(i);
if (!usedCodePoints.add(codePoint) { // add() will return false if code point is
// already in the Set
return codePoint; // return the first recurring character
}
if (codePoint > 0xFFFF) {
i+=1;
}
}
return -1; // no recurring code points
}
-
1\$\begingroup\$ You should change
Set<int>
toSet<Integer>
. Java doesn't support primitive generic type parameters. \$\endgroup\$Eran– Eran2017年12月20日 08:04:41 +00:00Commented Dec 20, 2017 at 8:04