This is a two-part job:to identify a wordto find the top k wordsI've tried to use regex to split but it's taking 10x more time when string is really long. The top k strings are found using a priority queue. I've created a min priority queue for first k element, if the frequency of the next word is greater than the min element. I then remove min and insert the new word.  public static List<String> getTopStrings(String input, int k)        {            if(k<0)                throw new IllegalArgumentException(Value k cannot be negative for top k elements: k= +k);            List<String> list = new ArrayList<String>();            if(input==null || input.isEmpty() || k==0)            {                return list;            }            Set<Character> separators = new HashSet<Character>();            separators.add(' ');            separators.add(',');            separators.add('.');            separators.add(';');            separators.add(':');            separators.add('');            separators.add('(');            separators.add(')');            separators.add('-');            separators.add('/');            separators.add('\\');            separators.add('\'');            separators.add('?');            separators.add('\n');            separators.add('\r');            separators.add('!');            separators.add('|');            separators.add('~');            separators.add('\'');            separators.add('[');            separators.add(']');            separators.add('{');            separators.add('}');            separators.add('&');            separators.add('%');            separators.add('$');            separators.add('#');            separators.add('@');            separators.add('*');            separators.add('=');            separators.add('+');            separators.add('>');            separators.add('<');            final Map<String, Integer> wordMap = new HashMap<String, Integer>();            int count, wordStart=0;            for(int i=0;i<input.length();i++)            {                if(separators.contains(input.charAt(i)))                {                    addWord(input, wordMap,wordStart,i);                    wordStart=i+1;                }            }            addWord(input,wordMap,wordStart,input.length());            List<String> keySet = new ArrayList<String>();            keySet.addAll(wordMap.keySet());            if(keySet.size()<=k){                return keySet;            }            PriorityQueue<String> minHeap = new PriorityQueue<String>(k, new Comparator<String>() {                @Override                public int compare(String o1, String o2) {                    return (wordMap.get(o1)-wordMap.get(o2));                }            });            for(int i=0;i<k;i++)            {                minHeap.add(keySet.get(i));            }            for(int i=k;i<keySet.size();i++)            {                String key = keySet.get(i);                count = wordMap.get(key);                if(count>wordMap.get(minHeap.peek()))                {                    minHeap.poll();                    minHeap.add(key);                }            }            list.addAll(minHeap);            return list;        }        public static void addWord(String input, Map<String, Integer> wordMap, int startIndex, int endIndex)        {            int count = 0;            String word = input.substring(startIndex, endIndex).toLowerCase();            if(word!=null && !word.isEmpty())            {                if(wordMap.containsKey(word))                {                    count = wordMap.get(word);                }                wordMap.put(word, count+1);            }        }
Function to get top k words in a given String
java;strings;heap
Initialize Set with valuesYour method of initializing the hashset with values takes quite a bit of space. I would create a static field:public static final String[] SEPARATORS = new String[] {  , ,, ., ; };And then use it like this:public static final Set<String> separatorsSet = new HashSet<String>(Arrays.asList(SEPARATORS));Extract code to methodsYour getTopStrings method currently does three things: extract words from string, count amount of duplicate words, sort the result of that by frequency. I would at least create separate methods for the first two and the third functionality.Simplify SortingYour sorting mechanism using a queue seems overly complicated. If you are using Java 8, it could be reduced to three lines (or one really long one):    // sort by value, reversed    Stream<Entry<String, Integer>> sorted = wordMap.entrySet().stream().sorted(Map.Entry.comparingByValue((x,y) -> (y < x) ? -1 : ((x == y) ? 0 : 1))); // alternatively: use reversed and cast    // flatten map to list:    List<String> collected = sorted.map(entry -> entry.getKey()).collect(Collectors.toCollection(ArrayList::new));    // top k:    List<String> topK = collected.subList(0, k);Miscin Java, it is customary to place curly brackets on the same line as the opening statements.use curly brackets even for one line statements for improved readability and to avoid future bugs.use more spaces, eg around ==, <, +, after ;, etc for increased readability.declare variables in as small a scope as possible to increase readability.