How to return null for a character returning method in java?

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?

3 answers

  • answered 2021-09-25 15:14 João Dias

    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;
    }
    

  • answered 2021-09-25 15:20 Andy Turner

    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;
    }
    

  • answered 2021-09-25 16:58 Basil Bourque

    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 other 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 other 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.

    String rather than list of characters

    Of course in the code above you need not use code point integers given an input of strings with a single character each. You could just make a Set< String > rather than Set< Integer > for code points.

    Where the code points are useful is in tearing apart a string of multiple characters. So the calling programmer need not pass a collection of single-character strings. Instead, a String of several characters could be passed.

    public static Optional < String > firstRecurringCharacter ( String input )
    {
        Objects.requireNonNull( input );
        int[] codePoints = input.codePoints().toArray();
        Set < Integer > seen = new HashSet <>();
        for ( int codePoint : codePoints )
        {
            if ( ! seen.add( codePoint ) )
            {
                return Optional.of( Character.toString( codePoint ) );
            }
        }
        return Optional.empty();
    }
    

    Usage.

    String inputX = "DBCABA";
    String inputY = "DBCAET";
    String inputZ = "😷ABC😷ABC";
    
    System.out.println( App5.firstRecurringCharacter( inputX ).orElse( "No recurring characters." ) );
    System.out.println( App5.firstRecurringCharacter( inputY ).orElse( "No recurring characters." ) );
    System.out.println( App5.firstRecurringCharacter( inputZ ).orElse( "No recurring characters." ) );
    

    When run.

    B

    No recurring characters.

    😷

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum