Reputation: 55
I have created a method which takes in a hashmap as input, converts the values into an array, sorts the array using bubble sort and then I want it to use the sorted values to select the first N index keys from the initial hashmap. I understand this is not the best way to do this but that is fine (I have written this method as an alternative).
The method returns null since maxItems is empty and the "System.out.println(entry.getKey());" doesn't print anything to the console.
Thanks for any help!
public String[] getMaxListAlt(int n, HashMap<String, Integer> itemCount) {
itemCount.values().toArray();
Integer[] maxArray = itemCount.values().toArray(new Integer[0]);
int length = maxArray.length;
for (int i = 0; i < length-1; i++)
for (int j = 0; j < length-i-1; j++)
if (maxArray[j] > maxArray[j+1])
{
int temp = maxArray[j];
maxArray[j] = maxArray[j+1];
maxArray[j+1] = temp;
}
String[] maxItems = new String[n];
int maxIndex = n-1;
System.out.println(maxIndex);
for (int i=0; i >= n-1; i++) {
for (Map.Entry<String, Integer> entry : itemCount.entrySet()) {
if (entry.getValue().equals(maxArray[i])) {
System.out.println(entry.getKey());
maxItems[i] = entry.getKey();
}
}
}
for (int counts : maxArray) {
System.out.println(counts);
}
return maxItems;
}
Upvotes: 0
Views: 395
Reputation: 40064
If I understand what you are trying to do, here is another approach that you may be interested in. However, it seems that you may be doing a couple things incorrectly.
entrySet
you are getting repeated values since you always come to the first one with a certain number. But it may be a repeat of what you already have.The following streaming process works like this.
groupingBy
entryset
and sorts in descending order based on the values (the count)n
and maps the keys to the streamCreate some test data
Random r = new Random();
String[] v = r.ints(100, 'a', 'z' + 1)
.mapToObj(c -> (char) c + "").toArray(String[]::new);
int n = 10;
The streaming process
Map<String, Long> itemCount = Arrays.stream(v)
.collect(Collectors.groupingBy(a -> a, Collectors.counting()));
String[] result = itemCount.entrySet()
.stream()
.sorted(Entry.<String,Long>comparingByValue().reversed())
.limit(n).map(Entry::getKey).toArray(String[]::new);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i] + " --> " + itemCount.get(result[i]));
}
Prints something like
h --> 7
q --> 7
t --> 7
f --> 6
a --> 5
e --> 5
m --> 5
x --> 5
z --> 5
d --> 4
Note the first stream, if desired, could flow right into the second by streaming the entrySet()
. In that case you return the array and never see the actual map.
If you want to keep your original map
Here is a modification with comments if you want to use your original map and method.
public static String[] getMaxListAlt(int n,
Map<String, Long> itemCount) {
// copy entries to a list for sorting.
List<Entry<String,Long>> entries = new ArrayList<>(itemCount.entrySet());
// sort the entries based on value in reverse order.
entries.sort(Entry.<String,Long>comparingByValue().reversed());
// now create the array and just grab the top n items from the sorted
// entries list.
String[] maxItems = new String[n];
for (int i = 0; i < n; i++) {
maxItems[i] = entries.get(i).getKey();
}
return maxItems;
}
Upvotes: 1
Reputation: 1007
Your for
-loop doesn't run because you've got a typo - int i=0; i>= n-1;
but your i
can never be larger than your n-1
. Instead:
for (int i=0; i <= n-1; i++) {
for (Map.Entry<String, Integer> entry : itemCount.entrySet()) {
Upvotes: 2