i have HashMap<String,Double>hm1 and guava table Table<String, String, Double> employeeYearsOfService
HashMap hm1
fatima |0.97
AT&T |0.96
Table employeeYearsOfService
Google={Bill Smith=1.75, Stacy Lerner=11.5},
Microsoft={Bill Smith=13.2,Stacy Lerner=3.5},
AT&T={Bill Smith=2.0, Stacy Lerner=1.4},
fatima={Bill Smith=1.0, Stacy Lerner=2.0}
Table reseults
fatima={Bill Smith=1.0, Stacy Lerner=2.0}
AT&T={Bill Smith=2.0, Stacy Lerner=1.4}
and i want this result by create a new table Table<String, String, Double> results = HashBasedTable.create() contains a row of employeeYearsOfService
who have a same key with HashMap hm1 (this is my question)
this picture for mor understand
My Code
Table guava
Table<String, String, Double> employeeYearsOfService =
HashBasedTable.create();
employeeYearsOfService.put("AT&T", "Stacy Lerner", 1.4);
employeeYearsOfService.put("Microsoft", "Stacy Lerner", 3.5);
employeeYearsOfService.put("Microsoft", "Bill Smith", 13.2);
employeeYearsOfService.put("Google", "Stacy Lerner", 11.5);
employeeYearsOfService.put("AT&T", "Bill Smith", 2.0);
employeeYearsOfService.put("Google", "Bill Smith", 1.75);
employeeYearsOfService.put("fatima", "Bill Smith", 1.0);
employeeYearsOfService.put("fatima", "Stacy Lerner", 2.0);
hashmap hm1
HashMap<String, Double> hm = new HashMap<String, Double>();
HashMap<String, Double> hm1 = new HashMap<String, Double>();
System.out.println(employeeYearsOfService);
for (String key : employeeYearsOfService.rowKeySet()) {
for (Entry<String, Double> employee :
employeeYearsOfService.row(key).entrySet()) {
sum += employee.getValue() * operatCible.get(k);
sum2 += employee.getValue() * employee.getValue();
vect1 += operatCible.get(k) * operatCible.get(k);
Result = (sum / (sqrt(sum2) * sqrt(vect1)));
k++;
}
hm.put(key, Result);
k = 0;
sum = 0.0;
sum2 = 0.0;
vect1 = 0.0;
Result = 0.0;
}
System.out.println(hm);
Set<Entry<String, Double>> set = hm.entrySet();
List<Entry<String, Double>> list = new ArrayList<Entry<String, Double>>
(set);
Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
public int compare(Map.Entry<String, Double> o1,
Map.Entry<String, Double> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
System.out.println(list);
System.out.println("le K nn");
for (Entry<String, Double> entry : list.subList(0, 2)) {
hm1.put(entry.getKey(), entry.getValue());
}
loop for new Table
Table<String, String, Double> results = HashBasedTable.create();
System.out.println(hm1);
for (Entry<String, Double> entry : list) {
if(entry.getKey().equals(employeeYearsOfService.rowKeySet())){
results.put(employeeYearsOfService.row(entry.getKey())));
// how i do it
}
}
thank you very much
One way would consist of removing the elements you don't want from the table:
employeeYearsOfService.rowKeySet()
.removeIf(key -> !hm1.containsKey(key));
Here I'm using the Table.rowKeySet method to get the set of row keys from the table. This set is bounded to the original table, meaning that when an element is removed from this set, an entire row (with the same key) will be removed from the table. And this is what I'm doing with the Collection.removeIf method, whose predicate returns true if the key is not present in the hm1 map.
Related
I'm trying to convert the keys of a Map to Values of another Map, but finally only one key was return as Value. What was the problem?
when the program excuted I got different Result
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class KeystoValues {
public static void KtoV(Map<Double, Integer> Key) {
Map<Double, Integer> List = new HashMap<Double, Integer>();
Map<Integer, Double> KeystoV = new HashMap<Integer, Double>();
System.out.println("List Map\n");
List.putAll(Key);
for(Map.Entry<Double, Integer> val : List.entrySet()) {
System.out.println(val.getKey() + "," + val.getValue());
}
for(int h = 1; h<=List.size(); h++)
for(Map.Entry<Double, Integer> convert : List.entrySet()) {
Double j = convert.getKey();
KeystoV.put(h, j);
}
System.out.println("\nSet of keys in List Map now converted to set "
+ "of Values and stored to KeystoV Map\n\nKeystoV Map\n");
for(Map.Entry<Integer, Double> converted : KeystoV.entrySet()) {
System.out.println(converted.getKey() + "," + converted.getValue());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> Value = new ArrayList<Integer>();
Map<Double, Integer> Key = new HashMap<Double, Integer>();
Key.put(45.0,1);
Key.put(40.0,2);
Key.put(23.0,2);
Key.put(25.0,3);
Key.put(0.0,1);
KtoV(Key);
}
}
List Map
0.0,1
25.0,3
40.0,2
45.0,1
23.0,2
Set of keys in List Map now converted to set of Values and stored to KeystoV Map
KeystoV Map
1,23.0
2,23.0
3,23.0
4,23.0
5,23.0
The problem with your code is this nested for loop:
for(int h = 1; h<=List.size(); h++)
for(Map.Entry<Double, Integer> convert : List.entrySet()) {
Double j = convert.getKey();
KeystoV.put(h, j);
}
If you debug it, then you'll see that you are always putting the last iterated value of List.entrySet() as the value of all keys.
Try changing it to:
int index = 1;
for (Map.Entry<Double, Integer> convert : List.entrySet()) {
KeystoV.put(index, convert.getKey());
index++;
}
You have to use a list for the second map values because some of your values could appear twice and that would result in duplicate keys which maps can't support.
Collectors.groupingBy creates a map using a supplied key
Collectors.mapping gets the key as the value for entry into the value which is a list of doubles.
Try it like this.
Map<Double, Integer> map = Map.of(2.0, 1, 3.0, 1, 8.0, 5, 9.0, 7, 4.0, 7);
Map<Integer, List<Double>> keystoV = map.entrySet().stream().collect(Collectors.groupingBy(Entry::getValue,
Collectors.mapping(Entry::getKey, Collectors.toList())));
map.entrySet().forEach(System.out::println);
System.out.println();
keystoV.entrySet().forEach(System.out::println);
prints
9.0=7
8.0=5
2.0=1
3.0=1
4.0=7
1=[2.0, 3.0]
5=[8.0]
7=[9.0, 4.0]
Here is a loop version using the Map.computeIfAbsent method.
if key is absent, create a list for that key.
it also returns the list so the new value (old key) many be added to the list.
keystoV.entrySet().forEach(System.out::println);
Map<Integer, List<Double>> result = new HashMap<>();
for(Entry<Double, Integer> e : map.entrySet()) {
result.computeIfAbsent(e.getValue(), v->new ArrayList<>()).add(e.getKey());
}
result.entrySet().forEach(System.out::println);
prints
1=[2.0, 3.0]
5=[8.0]
7=[9.0, 4.0]
I have a list of users (stored in a properties file) that have a level. I sort the users by their level and then send the sorted list back to the guild. I paginate the list, but its still showing all of the users instead of just 10 per page.
Map<String, Integer> unsortedMap = new HashMap<String, Integer>();
for (String key : prop.stringPropertyNames()) {
String value = prop.getProperty(key);
unsortedMap.put(key, Integer.valueOf(value));
}
Map<String, Integer> sortedMap = sortByValue(unsortedMap);
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("aaaaaaaaaaaa");
ArrayList<Page> pages = new ArrayList<>();
for (Map.Entry<String, Integer> entry : sortedMap.entrySet()) {
String key = entry.getKey();
int value = entry.getValue();
if (key.contains(".level")) {
User users = ctx.getJDA().retrieveUserById(key.replace(".level", ""), true).complete();
eb.addField(users.getName(), String.valueOf(value), false);
}
}
for (int i = 0; i < sortedMap.size(); i++){
pages.add(new InteractPage(eb.build()));
}
channel.sendMessageEmbeds((MessageEmbed) pages.get(0).getContent()).queue(success -> {
Pages.paginate(success, pages, true);
});
}
private static Map<String, Integer> sortByValue(Map<String, Integer> unsortedMap) {
List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(unsortedMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
#Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return (o2.getValue().compareTo(o1.getValue()));
}
});
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : list) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
Partition the for loop into smaller parts using the for loop. Initialize the int outside of the loop and then increment the int for every entry and then divide the int by how many items you want displayed on the list. Ex:
int i = 0;
for (Map.Entry<String, Integer> entry : sortedMap.entrySet()) {
i++;
if (i % 6 == 0) {
//add page here
I have two HashMap<String, Integer> How can I get the average of the values?
HashMap<String, Integer> map1 = ...
map1.put("str1", 7);
map1.put("str2", 4);
HashMap<String, Integer> map2 = ...
map2.put("str1", 3);
map2.put("str2", 2);
The expected output is:
("str1") = 5;
("str2") = 3;
I am able to retrieve the sum of two maps as follows:
map2.forEach((k, v) -> map1.merge(k, v, Integer::sum));
But how can I retrieve the average of two maps using Java 8?
Update:
At the request of # I am posting a larger portion of my code:
HashMap<String, HashMap<String, Double>> map;
HashMap<String, Double> map2 = new HashMap<String, Double>();
map = func1();
map = func2();
map = func3();
for (Entry<String, HashMap<String, Double>> entry : map.entrySet()) {
String key = entry.getKey();
HashMap<String, Double> mp = map.get(key);
mp.forEach((k, v) -> map2.merge(k, v, (t, u) -> (t + u) / 2));
for (Entry<String, Double> entry1 : mp.entrySet()) {
StringfieldName = entry1.getKey();
Double score= entry1.getValue();
System.out.println(fieldName.toString() + " = " + score);
}
}
return map2;
}
Did you tried to do this :
map1.forEach((k, v) -> map1.merge(k, v, (t, u) -> (t + u) / 2));
Why not take advantage of Java 8 features altogether?
double avg = Stream.of(map1.values(), map2.values())
.map(set -> set.stream().collect(Collectors.summingInt(Integer::intValue)))
.collect(Collectors.averagingDouble(Integer::doubleValue));
I have this program and I want to gather values in ArrayList operatCible and values in Table employeeYearsOfService and I want to stock the result in HashMap<String,integer> witch contains RowKey and result.
I don't know how to do it. This what I want
Code
public class collaborativAlgorithme {
Table<String, String, Double> employeeYearsOfService =
HashBasedTable.create();
public static void main(String[] args) {
List<Double> operatCible = new ArrayList<Double>();
operatCible.add(4.1);
operatCible.add(5.0);
System.out.println(operatCible);
Table<String, String, Double> employeeYearsOfService =
HashBasedTable.create();
employeeYearsOfService.put("AT&T", "Stacy Lerner", 1.4);
employeeYearsOfService.put("Microsoft", "Stacy Lerner", 3.5);
employeeYearsOfService.put("Microsoft", "Bill Smith", 13.2);
employeeYearsOfService.put("Google", "Stacy Lerner", 11.5);
employeeYearsOfService.put("AT&T", "Bill Smith", 2.0);
employeeYearsOfService.put("Google", "Bill Smith", 9.75);
System.out.println(employeeYearsOfService.rowKeySet());
HashMap<String,Integer> result=new HashMap<String,Integer>;
System.out.println(employeeYearsOfService);
Map<String, Double> attEmployees = employeeYearsOfService.row("AT&T");
for (Map.Entry<String, Double> employee : attEmployees.entrySet()) {
// what i do??
// sum values arraylist and values table
System.out.println("Employee Name: " + employee.getKey() + ", Years
of Service: " + employee.getValue());
}
}
}
I solved my problem
And I add something else as (sqrt)....
this is the code
int k = 0;
Double sum = 0.0;//cosine similarity
Double sum2 = 0.0;
System.out.println(employeeYearsOfService);
for (String key : employeeYearsOfService.rowKeySet()) {
HashMap<String, Double> hm = new HashMap<String, Double>();
for (Entry<String, Double> employee :
employeeYearsOfService.row(key).entrySet()) {
sum += employee.getValue() * operatCible.get(k);
sum2+=employee.getValue();
k++;
}
k = 0;
System.out.println(sum);
System.out.println("----");
System.out.println(sqrt(sum2));
hm.put(key, sum);
sum = 0.0;
System.out.println(hm);
}
}
you ca dou that
HashMap<String, Double> hm = new HashMap<String, Double>();
System.out.println(employeeYearsOfService);
for (String key : employeeYearsOfService.rowKeySet()) {
for (Entry<String, Double> employee :
employeeYearsOfService.row(key).entrySet()) {
sum += employee.getValue() + operatCible.get(k);
k++;
}
k = 0;
System.out.println(sum);
hm.put(key, sum);
}
I want to get the person having highest values from all the tables. Below is the example which i retrieve from db
Id play(count) listen(count) display(count) comment(count)
a 3 1 4 2
b 2 5 3 7
c 6 3 0 1
d 0 0 5 4
e 6 4 8 9
f 4 2 5 7
in this all counts related to same id but coming from different tables.Here I want e(6,4,8,9) as sorting output. How can i do this sorting?
Try something like this:
Map<String, List<Integer>> map = new LinkedHashMap<>();
// Assuming that you are working with query output resultset
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
List<Integer> li = new ArrayList<>();
li.add(rs.getInt("PLAY"));
li.add(rs.getInt("LISTEN"));
li.add(rs.getInt("DISPLAY"));
li.add(rs.getInt("COMMENT"));
map.put(rs.getString("ID"), li);
}
} catch (SQLException e ) {
/* SQLException handler */
} finally {
if (stmt != null) { stmt.close(); }
}
map = sortByValues(map);
for (Map.Entry<String, List<Integer>> entry: map.entrySet()) {
System.out.println(entry.getKey() + "," + entry.getValue());
}
}
public static Map<String, List<Integer>> sortByValues(Map<String, List<Integer>> map) {
List<Map.Entry<String, List<Integer>>> list =
new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, List<Integer>>>() {
public int compare(Map.Entry<String, List<Integer>> m1, Map.Entry<String, List<Integer>> m2) {
int sum1 = 0;
for(Integer d : m1.getValue())
sum1 += d;
int sum2 = 0;
for(Integer d : m2.getValue())
sum2 += d;
return (new Integer(sum2)).compareTo(new Integer(sum1));
}
}) ;
Map<String, List<Integer>> result = new LinkedHashMap<>();
for (Map.Entry<String, List<Integer>> entry: list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
Note: I have a separate method sortByValues() to do the comparison. This makes code neat to read and reusable rather than implementing an anonymous block after try-catch.
What's happening here?
Our aim is to sort IDs by different values fetched from Database. I feel Map data structure to be the apt one here. Example Map which is represented in a generic way as Map<String, List<Integers>>.
Map<String, List<Integer>> map = new LinkedHashMap<>();
Creates the linked hash map to store the pair
List<Integer> li = new ArrayList<>();
Creates an Arraylist object inside while loop to store each value fetched from database. It's scope dies within this loop.
map.put(id, li);
Adds each users id and values in the format Map<String, List<Integer>>
map = sortByValues(map);
Accesses the static sortByValues() to fetch the sorted map based on values it has.
sortByValues(Map<String, List<Integer>> map)
Overrides the Comparator's compare() anonymously and performs sorting based upon values. It sums up each ID's value and does the comparison.
Mock Execution:
Map<String, List<Integer>> map = new LinkedHashMap<>();
// Map<String, List<Integer>> map = new HashMap<>();
List<Integer> li = new ArrayList<>();
li.add(1);
li.add(2);
li.add(3);
// MathUtils.sum()
map.put("a", li);
// map.put("a", 5);
List<Integer> li2 = new ArrayList<>();
li2.add(3);
li2.add(-1);
li2.add(1);
map.put("b", li2);
List<Integer> li3 = new ArrayList<>();
li3.add(10);
li3.add(-1);
li3.add(9);
map.put("c", li3);
map = sortByValues(map);
for (Map.Entry<String, List<Integer>> entry: map.entrySet()) {
System.out.println(entry.getKey() + "," + entry.getValue());
}
Result:
c,[10, -1, 9]
a,[1, 2, 3]
b,[3, -1, 1]