1

Is there a way to put list elements to a String array in java? I sorted a Map by value using a custom Comparator and now trying to put the key(String) elements into an array. The only way I found is looping through the array and the sorted list at the same time and fill up the array that way but it only puts the last element into it.

Example: My map without sorting: {a=5, b=2, c=8, d=1}

After sorted with custom Comparator: [c=8, a=5, b=2, d=1]

Now I simply need to put the key values (c,a etc.) to the tuple final String[] lettersWithBigValues = new String[n] where n is the length of the tuple.

However, after:

for (int i = 0; i < Integer.parseInt(args[1]); i++) { System.out.println(lettersWithBigValues[i]+","); }

The console gives back: d,d,d,d given that the console line argument is 4

Here is the full function:

public String[] getTopLettersWithValues(final int n){
        final String[] lettersWithBigValues = new String[n];

        final Map<String, Integer> myMap = new HashMap<>();

        int counter = 0;

        for (final List<String> record : records) {

            if (!myMap.containsKey(record.get(1))) {
                myMap.put(record.get(1), counter += Integer.parseInt(record.get(4)));
            } else {
                myMap.computeIfPresent(record.get(1), (k,v) -> v + Integer.parseInt(record.get(4)));
            }
        }

        System.out.println(myMap);

        List<Map.Entry<String, Integer>> sorted = new LinkedList<>(myMap.entrySet());

        // Sort list with list.sort(), using a custom Comparator
        sorted.sort(valueComparator);

        System.out.println(sorted);

        for (int i = 0; i < lettersWithBigValues.length; i++) {
            for (Map.Entry<String, Integer> values: sorted) {
                lettersWithBigValues[i] = values.getKey();
            }
        }
         return lettersWithBigValues;
    }

Where records is a List of data read from a csv file.

And here is the comparator:

    public Comparator<Map.Entry<String, Integer>> valueComparator = (o1, o2) -> {

        Integer v1 = o1.getValue();

        Integer v2 = o2.getValue();

        return v2.compareTo(v1);
    };
Dzsonah
  • 125
  • 1
  • 11
  • Check if this respond to your question: https://stackoverflow.com/questions/16203880/get-array-of-maps-keys – nourhero Mar 17 '20 at 17:17
  • what if you have odd number of entries in your input map, how would you form the tuples then? what is your expected output? – Naman Mar 17 '20 at 17:19
  • @Naman Odd number of entries would never occur as they are read from a csv file. My expected output is a String tuple with all the key values(however a list has no key values as far as I'm aware) from the sorted list. But somehow I'm still able to put d into the tuple and that is what I don't really understand. – Dzsonah Mar 17 '20 at 17:29
  • @DanielBenedek You would need to share the code used in the transformation from the input map to the sorted map for further clarification. – Naman Mar 17 '20 at 17:32
  • @Naman I updated the link above have a look please – Dzsonah Mar 17 '20 at 17:35
  • You must [edit the question](https://stackoverflow.com/posts/60727100/edit) and paste that block of code in the question itself and not as an image. Also, add the `valueComparator` logic to the question while you do that for anyone else to be able to help. – Naman Mar 17 '20 at 17:37
  • @Naman Should be good now – Dzsonah Mar 17 '20 at 17:43

3 Answers3

1

You can attain the array of keys as follows:

String [] lettersWithBigValues = myMap.entrySet().stream() // entries of your intial map
        .sorted(valueComparator) // sorted by your comparator
        .map(Map.Entry::getKey) // mapped to only the key e.g. 'd', 'a'
        .toArray(String[]::new); // converted to array
Naman
  • 27,789
  • 26
  • 218
  • 353
0

Seems to me that you have mistakenly used a nested for loop, you just need the one:

for (int i = 0; i < lettersWithBigValues.length; i++) {
     lettersWithBigValues[i] = sorted.get(i).getKey();
}

That would return the array: c, a, b, d

leo277
  • 439
  • 2
  • 7
0

As an added suggestion you could also have created the Comparator using the Entry.comparingByValue() method.

Comparator<Entry<String,Integer>> valueComparator = 
                Entry.<String,Integer>comparingByValue().reversed();

It returns a ready made Comparator that compares by the natural order of the value. So to sort in reverse, you just need to tag on the reversed() method which is defined in the Comparator interface.

WJS
  • 36,363
  • 4
  • 24
  • 39