Function to get top k words in a given String This is a two-part job:


to identify a word
to find the top k words


I'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&lt;String&gt; getTopStrings(String input, int k)
        {
            if(k&lt;0)
                throw new IllegalArgumentException("Value k cannot be negative for top k elements: k= "+k);
            List&lt;String&gt; list = new ArrayList&lt;String&gt;();
            if(input==null || input.isEmpty() || k==0)
            {
                return list;
            }
            Set&lt;Character&gt; separators = new HashSet&lt;Character&gt;();
            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('&amp;');
            separators.add('%');
            separators.add('$');
            separators.add('#');
            separators.add('@');
            separators.add('*');
            separators.add('=');
            separators.add('+');
            separators.add('&gt;');
            separators.add('&lt;');

            final Map&lt;String, Integer&gt; wordMap = new HashMap&lt;String, Integer&gt;();
            int count, wordStart=0;
            for(int i=0;i&lt;input.length();i++)
            {
                if(separators.contains(input.charAt(i)))
                {
                    addWord(input, wordMap,wordStart,i);
                    wordStart=i+1;
                }
            }
            addWord(input,wordMap,wordStart,input.length());
            List&lt;String&gt; keySet = new ArrayList&lt;String&gt;();
            keySet.addAll(wordMap.keySet());
            if(keySet.size()&lt;=k){
                return keySet;
            }

            PriorityQueue&lt;String&gt; minHeap = new PriorityQueue&lt;String&gt;(k, new Comparator&lt;String&gt;() {
                @Override
                public int compare(String o1, String o2) {
                    return (wordMap.get(o1)-wordMap.get(o2));
                }
            });

            for(int i=0;i&lt;k;i++)
            {
                minHeap.add(keySet.get(i));
            }
            for(int i=k;i&lt;keySet.size();i++)
            {
                String key = keySet.get(i);
                count = wordMap.get(key);
                if(count&gt;wordMap.get(minHeap.peek()))
                {
                    minHeap.poll();
                    minHeap.add(key);
                }
            }
            list.addAll(minHeap);
            return list;
        }
        public static void addWord(String input, Map&lt;String, Integer&gt; wordMap, int startIndex, int endIndex)
        {
            int count = 0;
            String word = input.substring(startIndex, endIndex).toLowerCase();
            if(word!=null &amp;&amp; !word.isEmpty())
            {
                if(wordMap.containsKey(word))
                {
                    count = wordMap.get(word);
                }
                wordMap.put(word, count+1);
            }
        }
Initialize Set with values

Your 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&lt;String&gt; separatorsSet = new HashSet&lt;String&gt;(Arrays.asList(SEPARATORS));


Extract code to methods

Your 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 Sorting

Your 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&lt;Entry&lt;String, Integer&gt;&gt; sorted = wordMap.entrySet().stream().sorted(Map.Entry.comparingByValue((x,y) -&gt; (y &lt; x) ? -1 : ((x == y) ? 0 : 1))); // alternatively: use reversed and cast
    // flatten map to list:
    List&lt;String&gt; collected = sorted.map(entry -&gt; entry.getKey()).collect(Collectors.toCollection(ArrayList::new));
    // top k:
    List&lt;String&gt; topK = collected.subList(0, k);


Misc


in 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 ==, &lt;, +, after ;, etc for increased readability.
declare variables in as small a scope as possible to increase readability.