2
\$\begingroup\$

I am looking to hide an email id name, by only showing first 4 letters of the email. The code works fine. Looking for opinion if I could make it better, more readable and maybe even more efficient if possible. I am using Commons lang library for this and wondering if that is an unnecessary overhead.

Please look for the comment <-- HERE -->. I am looking for opinion in this region. I am using Java 7, no way around that.

import org.apache.commons.lang.StringUtils;
import java.util.HashMap;
import java.util.Map;

public class App {
    public static void main(String[] args) {

        //all these prints out as expected.

        String newEmail1 = getEmail("sample1");
        System.out.println("Expected: some**@gmail.com | actual: " + newEmail1);

        String newEmail2 = getEmail("sample2");
        System.out.println("Expected: null | actual: " + newEmail2);

        String newEmail3 = getEmail("short");
        System.out.println("Expected: q**@gmail.com | actual: " + newEmail3);

        String newEmail4 = getEmail("noname");
        System.out.println("Expected: null | actual: " + newEmail4);
    }

    private static String getEmail(String param){
        //added these solely for testing to show
        Map<String, String> emails = new HashMap<>();
        emails.put("sample1", "someone@gmail.com");
        emails.put("short", "qw@gmail.com");
        emails.put("noname", "@gmail.com");
        //added these solely for testing to show

        //I am looking for opinions from here onwards. <-- HERE -->
        String emailAddress = emails.get(param);
        if(emailAddress != null){
            String emailAddressFront = StringUtils.substringBefore(emailAddress, "@");
            String emailAddressBack = StringUtils.substringAfter(emailAddress, "@");

            // i need to hide emails by only revealing first 4 characters.
            // but also need to check in case email name is shorter than 4.
            if(emailAddressFront.isEmpty()){
                return null;
            }
            int shortenedLength = 4;
            int emailNameLength = emailAddressFront.length();
            if(emailNameLength < 4){
                shortenedLength = emailNameLength - 1;
            }
            emailAddress = emailAddressFront.substring(0, shortenedLength) + "**@" + emailAddressBack;
        }
        return emailAddress;
        //I am looking for opinions till here. <-- HERE -->
    }
}
\$\endgroup\$
  • \$\begingroup\$ Looks like there's a java.mail.internet.InternetAddress class that may do the email parsing you want (ie can return just the front). I found the documentation for Java EE 7, can't find anything newer. \$\endgroup\$ – esote Oct 22 '18 at 22:05
2
\$\begingroup\$

Guard clauses are easier to read than nested blocks.

It will be somewhat more efficient to track the index of the @ sign rather than using substrings. You definitely don’t need Apache commons.

Try not to reassign variables if you can help it. In this case, you can leverage a StringBuilder to mutate your email address into a new String. The replace method is particularly applicable.

Using the above ideas, you could change your code to look more like:

private static String getEmail(final String param){
    final Map<String, String> emails = new HashMap<>();
    emails.put("sample1", "someone@gmail.com");
    emails.put("short", "qw@gmail.com");
    emails.put("noname", "@gmail.com");

    final String emailAddress = emails.get(param);
    if (emailAddress == null) {
        return null;
    }

    final int atIndex = emailAddress.indexOf('@');
    if (atIndex == 0) {
        return null;
    }

    final StringBuilder maskedEmailAddress = new StringBuilder(emailAddress);
    if (atIndex < 4) {
        maskedEmailAddress.replace(1, atIndex, "**");
    } else {
        maskedEmailAddress.replace(4, atIndex, "**");
    }

    return maskedEmailAddress.toString();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.