Avoid basic style errors
Refactoring an original method into smaller pieces has several advantages:
Example
Here, the method parseSearchText
, which was originally monolithic,
has been refactored to call several private
methods which perform
very well-defined, simple tasks.
Boolean conditions can often benefit from being placed in their own
method. Here, isDoubleQuote
, isCommonWord
, and textHasContent
are all examples of this.
import java.util.*; /** The user enters text into a search box. This class is used to parse that text into specific search terms (or tokens). It eliminates common words, and allows for the quoting of text, using double quotes. JDK 7+. */ public final class SearchBoxParser { public static void main(String... arguments) { SearchBoxParser parser = new SearchBoxParser("mars venus \"milky way\" sun"); Set<String> tokens = parser.parseSearchText(); //display the tokens System.out.println(tokens); } /** @param searchText is non-null, but may have no content, and represents what the user has input in a search box. */ public SearchBoxParser(String searchText) { if (searchText == null) { throw new IllegalArgumentException("Search Text cannot be null."); } this.searchText = searchText; } /** Parse the user's search box input into a Set of String tokens. @return Set of Strings, one for each word in fSearchText; here "word" is defined as either a lone word surrounded by whitespace, or as a series of words surrounded by double quotes, "like this"; also, very common words (and, the, etc.) do not qualify as possible search targets. */ public Set<String> parseSearchText() { Set<String> result = new LinkedHashSet<>(); boolean returnTokens = true; String currentDelims = WHITESPACE_AND_QUOTES; StringTokenizer parser = new StringTokenizer( searchText, currentDelims, returnTokens ); String token = null; while (parser.hasMoreTokens()) { token = parser.nextToken(currentDelims); if (!isDoubleQuote(token)){ addNonTrivialWordToResult(token, result); } else { currentDelims = flipDelimiters(currentDelims); } } return result; } // PRIVATE private String searchText; private static final Set<String> COMMON_WORDS = new LinkedHashSet<>(); private static final String DOUBLE_QUOTE = "\""; //the parser flips between these two sets of delimiters private static final String WHITESPACE_AND_QUOTES = " \t\r\n\""; private static final String QUOTES_ONLY ="\""; /**Very common words to be excluded from searches.*/ static { COMMON_WORDS.add("a"); COMMON_WORDS.add("and"); COMMON_WORDS.add("be"); COMMON_WORDS.add("for"); COMMON_WORDS.add("from"); COMMON_WORDS.add("has"); COMMON_WORDS.add("i"); COMMON_WORDS.add("in"); COMMON_WORDS.add("is"); COMMON_WORDS.add("it"); COMMON_WORDS.add("of"); COMMON_WORDS.add("on"); COMMON_WORDS.add("to"); COMMON_WORDS.add("the"); } /** * Use to determine if a particular word entered in the * search box should be discarded from the search. */ private boolean isCommonWord(String searchTokenCandidate){ return COMMON_WORDS.contains(searchTokenCandidate); } private boolean textHasContent(String text){ return (text != null) && (!text.trim().equals("")); } private void addNonTrivialWordToResult(String token, Set<String> result){ if (textHasContent(token) && !isCommonWord(token.trim())) { result.add(token.trim()); } } private boolean isDoubleQuote(String token){ return token.equals(DOUBLE_QUOTE); } private String flipDelimiters(String currentDelims){ String result = null; if (currentDelims.equals(WHITESPACE_AND_QUOTES)){ result = QUOTES_ONLY; } else { result = WHITESPACE_AND_QUOTES; } return result; } }