1

I have a question about Maps, from the type Integer,Integer. I made a mistake by solving a problem based on <Integer,Integer> map on <String,String>, the end result was correct however, the order of numbers was not descending. That would be solved if I chose Integer instead of Strings.

How can I take the input from the user and assign it to keys/values of my map when it is Map<Integer, Integer>? I used substring() and indexOf() to make my old map but for integers I couldn't find a way

import java.util.*;
import java.io.*;
import type.lib.*;

public class MapTesting {
public static void main(String[] args) {
    PrintStream output = new PrintStream(System.out);
    Scanner input = new Scanner(System.in);

    Map<String,String> normal = new HashMap<String,String>();
    output.println("Enter your map, one key-value pair per line,");
    output.println("comma-separated. Use empty line as sentinel.");

    for ( String entry = input.nextLine(); entry.length() !=0;
        entry = input.nextLine()) {
        int comma = entry.indexOf(",");
        String key = entry.substring(0,comma);
        String value = entry.substring(comma+1);
        normal.put(key,value);
    }
    output.println("The input map is:");
    output.println(normal);

    Map<String,String> reverse = new HashMap<String,String>();
    boolean distinct = true;
    for (Map.Entry<String,String> entry : normal.entrySet()) {
        String keyY = entry.getKey();
        String valueE = entry.getValue();
        String existingReverseValue = reverse.get(valueE);

        if (existingReverseValue != null) {
            int currentValue = Integer.parseInt(existingReverseValue);
            int potentialNewValue = Integer.parseInt(keyY);
            if ( potentialNewValue < currentValue) {
                reverse.put(valueE,keyY);
            }
        } else {
            reverse.put(valueE,keyY);
        }
    }
    output.println("The inverted map [using the smaller key as a tie breaker]:");
    output.println(reverse);
    }
}
5
  • 1
    Assuming these Strings are the correct representation you want from your input, something as simple as int keyInt = Integer.valueOf(key) will get the integer of the number represented by the String. Commented Nov 25, 2014 at 15:25
  • @NoseKnowsAll i don't want to get the number represented by the string , i want to know if there is a way i can make this program with Map<Integer,Integer> using the same approach i did with strings.. to be more specific , how can i get the key/values from the user, as you can see i can easily do that by substring() and indexOf() i can locate what the user inputs.. Commented Nov 25, 2014 at 15:37
  • All user input is read as String or per single byte. If you read byte by byte, then good luck. If you read String by String, then you will need to convert String into Integer, and use this Integer however you want/need, which in this case seems to be the key and value for your Map. Commented Nov 25, 2014 at 15:40
  • @NoseKnowsAll that comment should be the answer. Commented Nov 25, 2014 at 15:50
  • @TJamesBoone God bless your soul, it works perfectly, i didn not know that i can locate using strings and then parse into integer .. that's too acvanced for me , but it works! Commented Nov 25, 2014 at 17:22

1 Answer 1

1

There are two steps you want to take:

  1. To move away from using Map<String, String> to Map<Integer, Integer>, you'll want to convert your input to an Integer before putting it in your map.
  2. Next, you'll want to extend HashMap and override the entrySet() method to return the entry set sorted by keys descending. This will also involve a custom implementation of the Comparator interface.

You can do this like so.

import java.util.*;
import java.io.*;

public class MapTesting {
    public static void main(String[] args) {
        PrintStream output = new PrintStream(System.out);
        Scanner input = new Scanner(System.in);

        Map<Integer, Integer> normal = new LinkedHashMap<Integer, Integer>();
        output.println("Enter your map, one key-value pair per line,");
        output.println("comma-separated. Use empty line as sentinel.");

        for ( String entry = input.nextLine(); entry.length() !=0;
              entry = input.nextLine()) {
            int comma = entry.indexOf(",");
            Integer key = Integer.parseInt(entry.substring(0,comma));
            Integer value = Integer.parseInt(entry.substring(comma+1));
            normal.put(key,value);
        }
        output.println("The input map is:");
        output.println(normal);

        // Here we make our reverse map an instance of our custom DescendingKeysMap.
        Map<Integer, Integer> reverse = new DescendingKeysMap();
        for (Map.Entry<Integer, Integer> entry : normal.entrySet()) {
            Integer keyY = entry.getKey();
            Integer valueE = entry.getValue();
            Integer existingReverseValue = reverse.get(valueE);

            if (existingReverseValue != null) {
                int currentValue = existingReverseValue;
                int potentialNewValue = keyY;
                if ( potentialNewValue < currentValue) {
                    reverse.put(valueE,keyY);
                }
            } else {
                reverse.put(valueE,keyY);
            }
        }
        output.println("The inverted map [using the smaller key as a tie breaker]:");
        output.println(reverse);
    }

    /**
     * Extends HashMap<Integer, Integer> and Overrides entrySet() to return the entries sorted by keys descending.
     */
    public static class DescendingKeysMap extends HashMap<Integer, Integer>{

        @Override
        public Set<Map.Entry<Integer, Integer>> entrySet() {
            List<Map.Entry<Integer, Integer>> entries = new ArrayList<Map.Entry<Integer, Integer>>(super.entrySet());
            // Sort
            Collections.sort(entries, new ByKeysDescending());
            return new LinkedHashSet<Map.Entry<Integer,Integer>>(entries);
        }
    }

    /**
     * Implements Comparator<Map.Entry<Integer, Integer>> to compare by the keys descending.
     */
    public static class ByKeysDescending implements Comparator<Map.Entry<Integer, Integer>> {
        @Override
        public int compare(Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) {
            // return the opposite of comparing the keys, to get a descending order
            return e1.getKey().compareTo(e2.getKey()) * -1;
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.