import java.util.*;
char[] characterArray1 = {'D', 'B', 'C', 'A', 'B', 'A'};
char[] characterArray2 = {'D', 'B', 'C', 'A', 'E', 'T'};
System.out.println(FRC(characterArray2));
public static char FRC(char[] array) {
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for(char character: array) {
if(hashMap.containsKey(character)) {
return character;
}else {
hashMap.put(character, 1);
}
}return null
}
characterArray1 is able to return character 'B' as it is the first recurring character
So how am I able to return null from a character returning method when I use characterArray2 as the argument?
CodePudding user response:
If you need to return null
, you need to make the return type the primitive wrapper type, Character
.
Also, there is no obvious need to use a Map
here: use a Set
, and use the return value of Set.add
as an indicator that the character was seen before:
public static Character FRC(char[] array) {
Set<Character> seen = new HashSet<>();
for (Character c : array) {
if (!seen.add(c)) {
return c;
}
}
return null;
}
CodePudding user response:
You need to use Character
which wraps a value of the primitive type char
in an object.
public static Character FRC(char[] array) {
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for(char character: array) {
if(hashMap.containsKey(character)) {
return character;
}else {
hashMap.put(character, 1);
}
}
return null;
}
CodePudding user response:
As the correct Answer by Andy Turner said, use a Set
for tracking individual objects rather than a Map
for pairs of objects.
Code point
The char
type (and its wrapper class Character
) is legacy, and is essentially broken. As a 16-bit value, it is not capable of representing most characters.
Instead, use code point integer numbers.
public static String firstRecurringCharacter ( List < String > inputs )
{
Objects.requireNonNull( inputs );
Set < Integer > seen = new HashSet <>();
for ( String s : inputs )
{
Objects.requireNonNull( s , "Input of list of String objects contained a null." );
if ( s.length() > 1) throw new IllegalStateException( "Input of list of String objects contained an element with more than one character." );
if ( ! seen.add( s.codePointAt( 0 ) ) )
{
return s;
}
}
return null;
}
Usage.
List < String > inputX = List.of( "D" , "B" , "C" , "A" , "B" , "A" );
List < String > inputY = List.of( "D" , "B" , "C" , "A" , "E" , "T" );
System.out.println( App5.firstRecurringCharacter( inputX ) );
System.out.println( App5.firstRecurringCharacter( inputY ) );
When run.
B
null
Optional
Returning null as a legitimate value is problematic. In such a case, use an Optional
wrapper.
public static Optional < String > firstRecurringCharacter ( List < String > inputs )
{
Objects.requireNonNull( inputs );
Set < Integer > seen = new HashSet <>();
for ( String s : inputs )
{
Objects.requireNonNull( s , "Input of list of String objects contained a null." );
if ( s.length() > 1 ) throw new IllegalStateException( "Input of list of String objects contained an element with more than one character." );
if ( ! seen.add( s.codePointAt( 0 ) ) )
{
return Optional.of( s );
}
}
return Optional.empty();
}
Usage.
List < String > inputX = List.of( "D" , "B" , "C" , "A" , "B" , "A" );
List < String > inputY = List.of( "D" , "B" , "C" , "A" , "E" , "T" );
System.out.println( App5.firstRecurringCharacter( inputX ).orElse( "No recurring characters." ) );
System.out.println( App5.firstRecurringCharacter( inputY ).orElse( "No recurring characters." ) );
When run.
B
No recurring characters.