Phone number duplication detector
Chomp the new line


    scan.nextLine();                // But why?



Nothing to do with performance, but Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo()? explains this.  

Remove unnecessary data structure


    String[] numbers = new String[total];



You never use numbers as an array.  You could get rid of it entirely.  


        numbers[i] = scan.nextLine();
        numbers[i] = convert(numbers[i]);
        if(!dict.containsKey(numbers[i])) {
            dict.put(numbers[i], 1);
        } else {
            dict.put(numbers[i], dict.get(numbers[i]) + 1);
        }



Replace numbers[i] with a single String.  

        String number = convert(scan.nextLine());

        Integer count = dict.get(number);
        if (count == null) {
            count = 0;
        }
        count++;

        dict.put(number, count);


Now we don't keep an array around for nothing.  

I also changed the get/put pattern.  This saves having to do both the containsKey check and the get.  

Consider other data structures


    Map&lt;String, Integer&gt; dict = new TreeMap&lt;String, Integer&gt;();



I would expect a TreeMap to be slower than a HashMap for most applications that depend on insert and read efficiency.  This is especially so since it sorts on keys and what you want is to find all with at least value 2.  You'd need to override the comparison to get that behavior.  

You don't use the read behavior that would be helpful.  And you accept the slower writes.  

        Map&lt;String, Integer&gt; dict = new HashMap&lt;&gt;();


This should perform faster for larger inputs.  

Pick the right method


    for(String number: dict.keySet()) {
        if(dict.get(number) &gt; 1) {
            hasDuplication = false;
            System.out.println(number + " " + dict.get(number));
        }
    }



This is the use case for an entrySet.  

    for (Map.Entry&lt;String, Integer&gt; entry : dict.entrySet()) {
        if (entry.getValue() &gt; 1) {
            hasDuplication = true;
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
    }


Now we don't have to do an expensive get lookup operation on each iteration.  

I'd also switch the meaning of hasDuplication to match the name.  Don't forget to switch it the other two places as well.  


    boolean hasDuplication = true;



to 

    boolean hasDuplication = false;


and 


    if(hasDuplication) {



to 

    if (!hasDuplication) {


Other possibilities

If this doesn't help, consider splitting reading the input from processing it.  So something like 

    for (int i = 0; i &lt; numbers.length; i++) {
        numbers[i] = scan.nextLine();
    }

    scan.close();

    for (String number : numbers) {
        number = convert(number);

        Integer count = dict.get(number);
        if (count == null) {
            count = 0;
        }
        count++;

        dict.put(number, count);
    }


I didn't test this, so you may have to declare a new variable rather than reusing number.