I have a Map with key as String and value as List as below
<Key>Path1 Value=[164,123,111,131]
<Key>Path2 Value=[164,122,135,133]
<Key>Path3 Value=[190,144,100,126]
<Key>Path4 Value=[113,122,453,117]
I want to compare each Key's Value with other Key's Value like Path1 Value with rest of Path's values and so on,
and also no duplicate comparision should happen, like if Path1 value is compared in 1st iteration . It should not compare Path2 with Path1 in 2nd iteration.
Am stuck with this problem . Please help me with any solution. Thanks in advance .
I have started with following code :
for (Map.Entry<String, List<String>> entry : map1.entrySet()) {
String key = entry.getKey();
for (String val : entry.getValue()) {
// do something with key and each val
}
}
Only compare keys where the first is less than the second, or some similar simple strategy.
for (String key1 : map.keySet()) {
for (String key2 : map.keySet()) {
if (key1.compareTo(key2) < 0) {
// compare key1 to key2
}
}
}
Maybe, this would be a better strategy than one suggested by Peter Lawrey cause it's not O(N*N)
Map<String, List<String>> map = new HashMap<>();
map.put("Path1", new ArrayList<>(Arrays.asList("164","123","111","131")));
map.put("Path2", new ArrayList<>(Arrays.asList("164","122","135","133")));
map.put("Path3", new ArrayList<>(Arrays.asList("190","144","100","126")));
map.put("Path4", new ArrayList<>(Arrays.asList("113","122","453","117")));
List<String> list = new LinkedList<>(map.keySet());
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
List<String> temp = new ArrayList<>(map.get(list.get(i)));
if (temp.removeAll(map.get(list.get(j)))) {
// do what you want
System.out.println(list.get(i) + " has duplicates with " + list.get(j));
}
}
}
Related
Need help to sort and efficiently print the same occurrences of the words in the below string.
Here is the occurrence for the string: {java=2, occurences=1, program=3, sample=1, the=2}
Expected output:
java=2,occurences=1,sample=1,the=2
String str = "sample program java program the occurences the java program";
String[] inputstr = str.split(" ");
TreeMap<String,Integer> map = new TreeMap<>();
for(String input: inputstr) {
if(map.containsKey(input)) {
int value = map.get(input);
map.put(input,value+1);
} else {
map.put(input,1);
}
}
You can simply convert the above code to a single line using java-8
Map<String, Long> countMap = Arrays.stream(inputstr)
.collect(Collectors.groupingBy(Object::toString, Collectors.counting()));
EDIT :
We need to find values in the map that have an occurrence of more than one. Achieved so using the following code :
// inversed the map using "google-guava.jar"
Multimap<Long, String> inverseMap = HashMultimap.create();
for (Entry<String, Long> entry : countMap .entrySet()) {
inverseMap.put(entry.getValue(), entry.getKey());
}
for (Entry<Long, Collection<String>> entry : inverseMap.asMap().entrySet()) {
// split the values into an array
Object[] split = entry.getValue().stream().toArray();
if (split != null && split.length > 1) {
for (int j = 0; j < split.length; j++) {
System.out.println(String.valueOf(split[j]) + " : "
+ countMap.get(String.valueOf(split[j])));
}
}
}
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 am a newbie in Java (coming from JavaScript developing on Adobe LiveCycle) and facing the following problem:
I have a String array with several items. I want to put only the items with the value "a" to a HashMap. But instead of 3 "a" values in the HashMap i get 1 null value there. Why is that?
String[] s = {"a", "a", "b", "a"};
Map m = new HashMap();
for (int i = 0; i < s.length; i++) {
if (s[i].equals("a")) {
m.put(i, s[i]);
}
}
for (int i = 0; i < m.size(); i++) {
System.out.println(m.get(i));
}
// Prints
//a
//a
//null
You are putting the items in the map with key 0, 1 and 3.
You are taking them out with key 0, 1, an 2.
Use:
for (Object o : m.keySet()) {
System.out.println(m.get(o));
}
or - better:
Map<Integer, String> m = new HashMap<>();
...
for (Integer i : m.keySet()) {
System.out.println(i + " -> " + m.get(i));
}
You put the items with their corresponding index in array s in the Map, i.e. you have a Map with content {0=a, 1=a, 3=a}. Therefore if you try to access the map with key 2 (m.get(2)), you get a null since key 2 is not found in m.
Instead of using a for-loop over m's size, I recommend iteration over m's keySet() via a foreach-loop:
for (Object key : m.keySet()) {
System.out.println("key: " + key + ", value: " + m.get(key));
}
On a sidenote: you are using raw types. You should bind the types of the Map and HashMap properly (see the Javadoc of Map for details): Map<Integer, String> m = new HashMap<Integer, String>();. With properly bound types, key in the for-loop can be of type int or Integer. I recommend type Integer to avoid unnecessary Auto(un)boxing.
Your code is working correctly, but you are accessing it not correctly.
String[] s = {"a", "a", "b", "a"};
for (int i = 0; i < s.length; i++) {
if (s[i].equals("a")) {
m.put(i, s[i]);
}
}
This puts it like this
First iteration : m.put(0, "a");
Second iteration : m.put(1, "a");
Third iteration : "b" doest not equal "a" but still counts the index i up
Fourth iteration: m.put(3, "a");
Apart from the other answers you can still use your range based loop and access it with an Iterator
Iterator<String> it = m.values().iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
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.
I have a string but cannot parse it into Map
string s="sakib hasan : 3 : sumon ali : 4 : tutul : 100
I need to create a HashMap from above string. sakib hasan,sumon ali,tutul,shila akter should be KEY of HashMap and 3,4,100,1, should be VALUEs of KEYs.
I have tried with the flowing code but unable to solve the problem
Map<String, Integer>amap=new HashMap<String,Integer>();
String[] splt=s.split(":");
for (String string : splt)
{
String[] pair=string.split(" ");
amap.put(pair[0])+Integer.parseInt(pair[1]);
}
Is there a way can I do this without hard coding
Try this.
Your split on ":" will return each item individually.
Then you just have to take each group as a set of two which you can account for in the for loop with i+=2
Map < String, Integer > amap = new HashMap < String, Integer > ();
String[] splt = s.split(" : ");
for (int i = 0; i < splt.length; i += 2) {
amap.put(splt[i],Integer.parseInt(splt[i + 1]));
}
In your code, your for loop is going through each element that you split and every single time, adding the hashmap only index 0 & 1. You need to increment the indices.
String s = "sakib hasan : 3 : sumon ali : 4 : tutul : 100 : shila akter : 1";
Map<String, Integer> amap = new HashMap<String, Integer>();
String[] splt = s.split(":");
for(int i = 1; i < splt.length;i+=2)
amap.put(splt[i-1].trim(), Integer.parseInt(splt[i].trim()));
Here is a similar solution using streams instead of a for loop:
IntStream.range(0, splt.length / 2)
.forEach(i -> map.put(splt[i], Integer.parseInt(splt[i + 1]));
Or you could turn the .forEach into a collector that creates the map.
At least,I got the answer
Map<String, Integer>amap=new HashMap<String,Integer>();
String[] splt=s.split(":");
try {
for (int i = 0; i <= pair.length; i +=2) {
amap.put(pair[i].trim(), Integer.parseInt(pair[(1 + i)].trim()));
}
} catch (Exception e) {
}