I have a data structures asgn I am working on. In it, we were required to create a HashMap of word objects (Word is a custom class). Where the key is a String, and the value is a custom Word object. From the HashMap I am required to create a treeMap that will sort the Word objects based on custom Word comparators I created. Thus far I have been able to sort the HashMap by creating the following Method which returns a SortedSet of Map.Entry:
public static SortedSet<Map.Entry<String , Word>> entriesSortedByValues
(Map<String , Word> map , Comparator<Word> comp){
SortedSet<Map.Entry<String , Word>> sortedEntries = new
TreeSet<Map.Entry<String , Word>>(
new Comparator<Map.Entry<String , Word>>()
{
public int compare(Map.Entry<String , Word> e1, Map.Entry<String , Word> e2)
{
int c = comp.compare(e1.getValue() , e2.getValue());
return c;
}
});
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
This works well, and returns the set ordered appropriately. However I now want to iterate over it to print the Word objects. Like so:
SortedSet t_set1 = entriesSortedByValues(h_Map , Word.alpha);
// this works^^ (returns correctly ordered set of Map.Entry<String , Word>)
for (Map.Entry<String , Word> entry : t_set_1)
{
System.out.println(///WORD OBJECT)
}
I have tried to run for loops over it, for each, and creater an iterator. I keep getting Incompatible Type Errors, or Entry has private access errors. This is probably a simple fix, but I have been banging my head against the wall trying everything to get it to work. PLZ HELP :(
You need to add the generic type of the SortedSet variable:
SortedSet<Map.Entry<String, Word>> t_set1 = entriesSortedByValues(h_Map , Word.alpha);
This is caused by generics being implemented with Type Erasure to maintain backwards compatibility with Java 1.4. By not adding the generic type you are effectively creating a SortedSet<Object>.
Related
I am trying to access the elements of the ArrayList that is the value of a map.
For example:
{"height": [-10,20]} and I am trying to get the individual value say "-10" in order to make a comparison in the when condition.
Right now i am doing:
rule "test"
when
Params(tol: tolerance) //recieving the Map
eval( tol.get("height").get(0) < 0 )
then
...
end
It says that the get function is not part of the type Object. How do i get to the arraylist value?
Assuming that your classes look something like this:
class Params {
private Map<String, List<Integer>> tolerance;
public Map<String, List<Integer>> getTolerance() { return this.tolerance; }
}
Then you should be able to structure a rule like this:
rule "test"
when
// get the Tolerance map and assign to $tolerance
Params( $tolerance: tolerance )
// get the 'height' list from the $tolerance map, assign to $height
Map( $height: this["height"] ) from $tolerance
// Check if the first integer in the $height list is negative
Integer( this < 0 ) from $height.get(0)
then
...
end
The this[ key ] syntax only works for Maps. Depending on how you've configured Drools and how old the version of Drools you're using is, $height may be extracted as an object, which means you'll have to first convert to list before you use the get(#) method.
Avoid eval whenever possible because the Drools compiler cannot optimize those calls.
So I'm going crazy with this one. This is for an assignment and can't seem to get this to work at all!!
I have the following HashMap:
HashMap<String, ArrayList<Team>> teams;
(Team being another class to obtain the details of the teams)
What I need to be able to do is get the List of teams for the Key(String) from the above HashMap, and assign the List to a local variable I have declared:
List<Team> results = teams.get(division);
But this is where I get stuck. I have no idea how I'm suppose to complete this task.
As a further note "division" is the Key used in the HashMap. The ArrayList is a list of teams that belong to the division.
I have tried the below, which does not compile at all. Really not sure how I can get this to work!!
public void recordResult(String division, String teamA, String teamB, int teamAScore, int teamBScore)
{
List<Team> results = teams.get(division);
for (String i : teams.keySet())
{
results = new ArrayList<Team>();
results.add();
}
}
**You can ignore the arguments after the "String division". These will be used later.
Iterate over the entrySet() of the Map. Now you can fetch each List for that specific key and proceed further. Something like:
for (Entry<String, ArrayList<Team>> entry : teams.entrySet()) {
// extract the value from the key using `teams.get(entry.getKey())`
// proceed further with the value obtained
}
I have a nested Map being returned by the Guava Library's Table structure that is templated as follows:
Map<ComplexID1, Map<ComplexID2, MyObject>>
where ComplexID1 is my row key, ComplexID2 is my column key and MyObject holds my metadata. One of the attributes of my metadata is a JODA timestamp.
I need to sort this whole structure chronologically (or reverse chronologically) for display, newest objects created at the top, going backwards.
I was unable to find any information to sort this data structure. Could someone please provide some pointers?
Further, I tried to have the MyObject class extend Comparable and override compareTo on the JODA datetime object because I was trying to use Collections.Sort(). Unfortunately, that approach does not seem to work for me.
The solution pointed to below solves the problem perfectly. The code snippet is taken from there. Pasting it here for reference, credit to the original poster (question was under a different title, hence could not find it).
Sorting Guava tables in descending order based on values
Ordering<Table.Cell<String, FlowId, VersionData>> comparator =
new Ordering<Table.Cell<String, FlowId, VersionData>>() {
public int compare(
Table.Cell<String, FlowId, VersionData> cell1,
Table.Cell<String, FlowId, VersionData> cell2) {
return cell1.getValue().compareTo(cell2.getValue());
}
};
ImmutableTable.Builder<String, FlowId, VersionData>
sortedBuilder = ImmutableTable.builder();
for (Table.Cell<String, FlowId, VersionData> cell :
comparator.reverse().sortedCopy(tableBackedVersionStore.cellSet()))
{
sortedBuilder.put(cell);
}
return sortedBuilder.build();
Java8 solution:
List l = table.rowMap()
.entrySet()
.stream()
.flatMap(row -> row.getValue().entrySet().stream()) //Flat row map
.sorted((col1, col2) -> col2.getValue().compareTo(col1.getValue()))
.collect(Collectors.toList());
I have the following list:
List<ArrayList> list;
list.get(i) contains the ArrayList object with the following values {p_name=set1, number=777002}.
I have to create a
Map<key,value>
where the key contains the p_name, and values are the numbers.
How to do it easily and fast as there can be hundreds of entries in the initial list and each number can be present in multiple p_name entries.
Update: Here is my current solution
List<Row> list; //here is my data
Map<String,String> map = new TreeMap<String,String>();
for (Row l : list) {
if (l.hasValues()) {
Map<String, String> values = l.getResult(); // internal method of Row interface that returns a map
String key = values.get( "number");
map.put(key, values.get( "p_name" ));
}
}
The method works, but maybe it could be done better?
PS : There is an obvious error in my design. I wonder if you find it :)
Sine the key can have more then one values, what you are looking for is a MultiMap. Multimap
Or a simple map in the form
Map<Key,ArrayList<Values>>
There is no "fast" way here to me. You still need to iterate through all the elements and check all the values.
And actually hundreds to Java is not much at all
I know answer to this question has been provided in many variants but I couldn't find it for my specific query.
I want to have a map which is sorted by values and I need to get it created before I put data into it. I came up with below code to create it
private Map<String, Integer> mapUserScore = new ConcurrentSkipListMap<>(new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
int i1=mapUserScore.get(o2);
int i2=mapUserScore.get(o1);
if(mapUserScore.get(o2)!=null && mapUserScore.get(o1)!=null){
int compare = mapUserScore.get(o2)-(mapUserScore.get(o1));
if(compare==0)compare=-1;
return compare;
}else
return 0;
}
});
So basically I want entries in map sorted by integer values in descending order so that highest scorers are on top.
However upon doing this when the first key-value pair is inserted, the program exits with below exception
Exception in thread "Thread-0" java.lang.StackOverflowError
at java.util.concurrent.ConcurrentSkipListMap.comparable(ConcurrentSkipListMap.java:658)
at java.util.concurrent.ConcurrentSkipListMap.doGet(ConcurrentSkipListMap.java:821)
at java.util.concurrent.ConcurrentSkipListMap.get(ConcurrentSkipListMap.java:1626)
Upon tracing, I found that line int i1=mapUserScore.get(o2) results in this exception.
Can anyone please help me to understand what could be the reason of stackoverflow here?
I am thinking that because before any item is stored in the map, code is trying to obtain it by using get() method to sort it and hence it goes into some recursive calls and results in exception.
If I understand correctly, you would like to be able to get the score associated to a name quickly (hence the need for a Map), and you would like to be able to iterate through tyhe name-score pairs with the highest scores first.
I would just use a HashMap<String, NameScore> (where the key is the name and the value is the name-score pair). This would give you O(1) lookups. And when you need to name-score pairs sorted by score, create a new ArrayList<NameScore> from the values() of the map, sort it, and return it.
The get() method uses the comparator to find the value. You can't use get in the comparator or your will get a stack over flow.
A simple work around is to include the score in the key and sort on that instead.
class NameScore implement Comparable<NameScore> {
String name;
int score;
}
BTW: When the comparator return 0 this means it is duplicate which is dropped. Unless you want only one name per score, you need to compare on the score AND the name.