Suppose I have a Map with m elements in it, like the following.
Map<String,Integer> mp = new HashMap<String,Integer>();
mp.put("Delhi",1);
mp.put("Bombay",1);
mp.put("Bangalore",1);
Here, m = 3. I would like to access the map of above elements in a cyclic order for specific number of times n, where n != m. Each time I access the Map I want to get the "next" element in the Map (so that implies that the Map entries are somehow ordered). If I get to the end of the Map I want to start over again at the beginning, since I want in all cases to access the map exactly n times. There is no relationship between n and m. Each time I access a map element I want to increase the value of that element by 1.
For example, given the above Map with 3 elements (m == 3), and supposing I want to access the Map five times in total (n == 5). The following should happen:
step-->String(Key)-->Integer(Value)
1-->Delhi-->2
2-->Bombay-->2
3-->Bangalore-->2
4-->Delhi-->3
5-->Bombay-->3
Any suggestions on this would be appreciated, even change of DataStructure as well.
I am specifically looking to loop through the map elements in tandem with an external loop.
What I don't want: suppose I have a for loop say
for(1 to numberofcycles)
{
for(iterate-->mapelements)
{
//looping mapelements
}
}
I would be looping through the map numberofcycles * numberofmap elements which is not what i am expecting to achieve.
Instead, I would like to achieve to loop through mapelements for exactly numberofcycles in cyclic order and changing/adding 1 to value after each visit.
i.e.
keep iterating through map in cyclic order until specific condition is reached.
As I understand it, you want to make a total of n trips, each one to a different destination, and you're visiting those destinations in a predefined order. How about something like this...
If you want to specify the order independent of the Map
Map<String,Integer> mp = new HashMap<>();
mp.put("Delhi",1);
mp.put("Bombay",1);
mp.put("Bangalore",1);
int numberOfTrips = 5;
List<String> orderOfVisits = Arrays.asList("Delhi", "Bombay", "Bangalore");
Iterator<String> visiterator = orderOfVisits.iterator();
for (int i = 0; i < numberOfTrips; i++) {
// Get a new iterator if we've exhausted the previous one
if (!visiterator.hasNext()) {
visiterator = orderOfVisits.iterator();
}
// Get the correct city and increment the counter
String key = visiterator.next();
mp.put(key, mp.get(key) + 1);
}
// demonstrate that the map contains the correct values
for (Entry<String, Integer> entry: mp.entrySet()) {
System.out.println("Key:" + entry.getKey() + ", Value:" + entry.getValue());
}
If you want the Map to govern the order
To visit the cities in the order in which they were added to the Map, you can do the following:
1) Change the declaration of mp from HashMap to LinkedHashMap:
Map<String,Integer> mp = new LinkedHashMap<>();
2) Iterate over the keyset of the Map:
visiterator = mp.keySet().iterator();
If you want to specify the order with a Comparator
1) Change the declaration of mp to TreeMap, supplying a Comparator:
Map<String,Integer> map = new TreeMap<>(Comparator.naturalOrder());
2) Iterate over the keyset of the Map as in the above example.
All the code
public static void tripsInConfigurableOrder() {
Map<String, Integer> mp = new HashMap<String, Integer>();
mp.put("Delhi", 1);
mp.put("Bombay", 1);
mp.put("Bangalore", 1);
int numberOfTrips = 5;
List<String> orderOfVisits = Arrays.asList("Delhi", "Bombay", "Bangalore");
Iterator<String> visiterator = orderOfVisits.iterator();
for (int i = 0; i < numberOfTrips; i++) {
if (!visiterator.hasNext()) {
visiterator = orderOfVisits.iterator();
}
String key = visiterator.next();
mp.put(key, mp.get(key) + 1);
}
for (Entry<String, Integer> entry : mp.entrySet()) {
System.out.println("Key:" + entry.getKey() + ", Value:" + entry.getValue());
}
}
public static void tripsInNaturalOrder() {
Map<String, Integer> mp = new LinkedHashMap<>();
mp.put("Delhi", 1);
mp.put("Bombay", 1);
mp.put("Bangalore", 1);
int numberOfTrips = 5;
Iterator<String> visiterator = mp.keySet().iterator();
for (int i = 0; i < numberOfTrips; i++) {
if (!visiterator.hasNext()) {
visiterator = mp.keySet().iterator();
}
String key = visiterator.next();
mp.put(key, mp.get(key) + 1);
}
for (Entry<String, Integer> entry : mp.entrySet()) {
System.out.println("Key:" + entry.getKey() + ", Value:" + entry.getValue());
}
}
public static void usingComparator() {
Map<String, Integer> mp = new TreeMap<>(Comparator.naturalOrder());
mp.put("Delhi", 1);
mp.put("Bombay", 1);
mp.put("Bangalore", 1);
int numberOfTrips = 5;
Iterator<String> visiterator = mp.keySet().iterator();
for (int i = 0; i < numberOfTrips; i++) {
if (!visiterator.hasNext()) {
visiterator = mp.keySet().iterator();
}
String key = visiterator.next();
mp.put(key, mp.get(key) + 1);
}
for (Entry<String, Integer> entry : mp.entrySet()) {
System.out.println("Key:" + entry.getKey() + ", Value:" + entry.getValue());
}
}
public static void main(String[] args) {
tripsInConfigurableOrder();
tripsInNaturalOrder();
usingComparator();
}
Map<String,Integer> mp = new HashMap<String,Integer>();
mp.put("Delhi",1);
mp.put("Bombay",1);
mp.put("Bangalore",1);
for (int i = 0 ; i < numberOfCycles; i++){
for (String key : mp.keySet()){
mp.put(key,mp.get(key)+1);
}
}
How about using the while loop and put iteration inside a while loop like this?
Map<String, Integer> map = ...
while (true or some condition)
{
for (Map.Entry<String, Integer> entry : map.entrySet())
{
map.put(key, map.get(key) + 1);
}
if (some condition met)
some condition = false
}
EDIT
I read your edited post and here is a solution to what you want to do.
You could use break to get out of the for loop when you reached maxCycle.
Map<String, Integer> map = ...
int numberOfCycles = 0;
int maxCycle = 10;
while (numberOfCycles < maxCycle)
{
for (Map.Entry<String, Integer> entry : map.entrySet())
{
if (++numberOfCycles < maxCycle)
map.put(key, map.get(key) + 1);
else
break;
}
}
Say you start from 0 and maxCycle is 5. If you have iterated 5 times, it will go to else and call break. After break you will go back to while loop and the exit condition is satisfied.
Related
I'm trying to print out only 10 values in this treemap, which I filled in from a hashmap.But all the ways I see to traverse the list only allows me to print out all the keys and values and not just 10.
TreeMap<Integer, String> displayTen = new TreeMap<Integer, String>();
displayTen.putAll(allValues);
for (Map.Entry m : displayTen.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
int count = 0;
TreeMap<K,V> resultMap = new TreeMap<K,V>();
for (Map.Entry<K,V> entry:source.entrySet()) {
if (count == 10)
break;
resultMap.put(entry.getKey(), entry.getValue());
count++;
}
return resultMap;
In my HashMap < String,List< String,String>> I saved keys (Name of a building) and values (Id´s from devices in this building).
I just want to get the size of values from each keys in my HashMap but the only size I get is from the first Key,Value pair...Here´s my code
Map<String, List<String>> moduleNamesWithAllParameters = new
HashMap<String, List<String>>();
List<String> parameters = new ArrayList<String>();
List<String> moduleNames = new ArrayList<String>();
Iterator it;
int start = 0, end = 0, mapKeys = 0;
parameters.add("kExmWoEM2HpMA4CT");
parameters.add("ILm1nApv06lDtqva");
parameters.add("gu00xoO5WPTv0SEr");
parameters.add("kX4FIg6c3C10msex");
parameters.add("xUcA4Y5rvqxlg8ju");
parameters.add("TYjydK6AyY7vwYSo");
parameters.add("#");
parameters.add("IDvHK1vXMiDEPxad");
parameters.add("ja0D3LH8ML0mQwZ0");
parameters.add("#");
parameters.add("tKgYRVvguvl3ByRc");
parameters.add("I95sFdAOoUTHjO7Y");
moduleNames.add("Building 1");
moduleNames.add("Building 2");
moduleNames.add("Building 3");
it = parameters.iterator();
for (int i = 0; i < moduleNames.size(); i++) {
do {
end++;
} while (it.hasNext() && !(it.next().equals("#")));
moduleNamesWithAllParameters.put(moduleNames.get(i), parameters.subList(start, end - 1));
start = end;
}
for (String key : moduleNamesWithAllParameters.keySet())
System.out.println(key + " = " + moduleNamesWithAllParameters.get(key));
Entry<String, List<String>> entry;
for (int i = 0; i < moduleNames.size(); i++) {
entry = moduleNamesWithAllParameters.entrySet().iterator().next();
mapKeys = entry.getValue().size();
System.out.println(mapKeys);
}
}
This line:
entry = moduleNamesWithAllParameters.entrySet().iterator().next();
Is constantly creating a new iterator over the entry set of the map and returning the first entry. So you will only ever see the first entry.
You can change the loop to loop over all entries like this:
for (Entry<String, List<String>> entry : moduleNamesWithAllParameters.entrySet()) {
mapKeys = entry.getValue().size();
System.out.println(mapKeys);
}
Assuming you're using Java8 or later:
moduleNamesWithAllParameters.entrySet().stream().forEach((entry) -> {
System.out.println(entry.getValue().size());
});
Replace your last loop with the following:
for (int i = 0; i < moduleNames.size(); i++) {
mapKeys = moduleNamesWithAllParameters.get(moduleNames.get(i)).size();
System.out.println(mapKeys);
}
Or a bit neater:
for(String key : moduleNamesWithAllParameters.keySet()) {
System.out.println(moduleNamesWithAllParameters.get(key).size());
}
Or even neater (Java 8+):
moduleNamesWithAllParameters.stream().forEach(entry ->
System.out.println(entry.getValue().getSize())
);
Or loop using valueSet (since you don't actually use the key):
for(List<String> value : moduleNamesWithAllParameters.valueSet()) {
System.out.println(value.size());
}
Or if you so fancy (Java 8+):
moduleNamesWithAllParameters.valueSet().stream().map(List::size).forEach(System.out::println);
Probleam is happend in this line:
entry = moduleNamesWithAllParameters.entrySet().iterator().next();
entrySet().iterator() is a new object each time it loops.
So you map size only is the first size.
I'm using this algorithm to compare two sets of values: a HashMap<Integer,ArrayList<Integer>> and the other ArrayList<Integer>. The goal of the program is to compare each value in the HashMap, with the values in the ArrayList, and returns a new HashMap of the similar values. So far, my program runs normally, but it returns false results.
ArrayList Example
[1.0.1.0.0]
HashMap Example
[1.0.1.1.0]
[0.1.1.0.0]
[0.1.1.1.0]
Result:
4
3
2
My Program
int k = 1;
List<Integer> listOperateur = new ArrayList<Integer>();
HashMap<Integer, Integer> sim = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, ArrayList<Integer>> e : hmm.entrySet()) {
count = 0;
for (Integer mapValue : e.getValue()) {
if (mapValue.equals(listOperateur.get(k))) {
count++;
}
}
sim.put(e.getKey(), count);
k++;
}
System.out.println("HASHMAP RESULT:");
LinkedHashMap<Integer, ArrayList<Integer>> hmm = new LinkedHashMap<>();
for (Entry<Integer, List<String>> ee : hm.entrySet()) {
Integer key = ee.getKey();
List<String> values = ee.getValue();
List<Integer> list5 = new ArrayList<>();
for (String temp : global) {
list5.add(values.contains(temp) ? 1 : 0);
}
hmm.put(key, (ArrayList<Integer>) list5);
}
//nouvelle list operateur
List<Integer> list6 = new ArrayList<Integer>();
System.out.println("liste operateur");
List<Integer> listOperateur = new ArrayList<Integer>();
listOperateur.add(1);
listOperateur.add(0);
listOperateur.add(0);
listOperateur.add(0);
Iterator iter = listOperateur.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
//calcule similarité
System.out.println("HASHMAP SIMILIRATE RESULT:");
HashMap<Integer, Integer> sim = new HashMap<Integer, Integer>();
int count;
int k = 0;
for (Map.Entry<Integer, ArrayList<Integer>> e : hmm.entrySet()) {
//if (e.getValue() != null) {
count = 0;
//you can move this part to another method to avoid deep nested code
for (Integer mapValue : e.getValue()) {
if (mapValue.equals(listOperateur.get(k))) {
count++;
}
}
sim.put(e.getKey(), count);
k++;
}
I believe you're attempting to rely on the insertion order of objects into the HashMap which is not wise, as order is not preserved. Instead, try changing hmm's type from HashMap to LinkedHashMap and see if that solves your problem.
Edit: Also, you should probably initialize k to 0 instead of 1.
I am currently trying to use a LinkedList to print a list of keys from their highest number of occurences to lowest. I am trying to use the sort method on the getValue method of the entry but it is not working. Any ideas what I'm doing wrong. Here is a snippet of my code
// Beginning tree map
Map<String, Integer> map1 = new TreeMap<>();
String[] words1 = text.split("[ \n\t\r.,;:!?(){ ]");
for (int i = 0; i < words1.length; i++)
{
String key = words1[i].toLowerCase();
if (key.length() > 0)
{
if (!map1.containsKey(key))
{
map1.put(key, 1);
}
else
{
int value = map1.get(key);
value++;
map1.put(key, value);
}
}
}
Set<Map.Entry<String, Integer>> entrySet1 = map1.entrySet();
// Get key and value from each entry
System.out.println("Treemap: " + map1);
for (Map.Entry<String, Integer> entry: entrySet1)
System.out.println(entry.getValue() + "\t" + entry.getKey());
System.out.println("");
// Beginning for LinkedList
LinkedList<Entry<String, Integer>> linkedList = new LinkedList<>(entrySet1);
System.out.println("linkedList:");
System.out.println(linkedList);
System.out.println(linkedList.sort(entrySet1.getKey());
With my current output
Treemap: {a=2, class=1, fun=1, good=3, have=3, morning=1, visit=1}
2 a
1 class
1 fun
3 good
3 have
1 morning
1 visit
linkedList:
[a=2, class=1, fun=1, good=3, have=3, morning=1, visit=1]
So my ultimate question is, how can i pass my getValue method to the LinkedList in order to print them in a sorted order.
I have this output and it comes out in the opposite order. The last printout is what i want to be the first print out. How can I reverse it? It is a HashMap.
System.out.println();
int c = 0;
System.out.print(newName + "= ");
for (Map.Entry<Integer, Integer> entry : result.entrySet()) {
System.out.print(entry.getValue() + "X^" + entry.getKey());
c++;
if (c != result.size()) {
System.out.print("+");
}
To preserve insertion order when iterating use a LinkedHashMap instead of a HashMap, and to go in reverse do this:
List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(result.entrySet());
Collections.reverse(entries);
for (Map.Entry<Integer, Integer> entry : entries) {
// same body as before
}
Alternatively, we can use a reverse iterator:
List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(result.entrySet());
ListIterator<Map.Entry<Integer, Integer>> iter = entries.listIterator();
while (iter.hasPrevious()) {
Map.Entry<Integer, Integer> entry = iter.previous();
// same body as before
}