Retrieve the first and second value from the map - java

What's the best way to get the first value and second value from the map.
I am trying to read the tableLists map and get the first and second value from the map.
Below is the code I have in which ReadTableConnectionInfo is the class.
private final LinkedHashMap<String, ReadTableConnectionInfo> tableLists;
ReadTableConnectionInfo table = tablePicker();
private ReadTableConnectionInfo tablePicker() {
Random r = new SecureRandom();
ReadTableConnectionInfo table;
if (r.nextFloat() < Read.percentageTable / 100) {
table = get first value from tableLists map
} else {
table = get second value from tableLists map
}
return table;
}

Assuming you are sure that your LinkedHashMap contains at least two values, you could do:
Iterator<Map.Entry<String, ReadTableConnectionInfo >> it = tableLists.entrySet().iterator();
if (r.nextFloat() < Read.percentageTable / 100) {
table = it.next().getValue();
} else { //since you have an else, you have to re-ignore the first value just below
it.next(); // ignoring the first value
table = it.next().getValue(); //repeated here in order to get the second value
}

Iteration of LinkedHashMap values is ordered by the insertion order. So values() is what you need:
Iterator it = values().iterator();
Object first = it.next().getValue();
Object second = it.next().getValue();

Related

How to create a HashMap that would have String as key and the value would be another HashMap from one list of custom object?

I have a list of custom object,
public class Assignmentsdata {
String assignmentId;
String teacherId;
String groupName;
String sectionId;
String levelId;
String startTime;
}
ArrayList<Assignmentsdata> list = new ArrayList<>();
lets say there are 20 elements in that list.
Now I want to get the output which is a hashmap of startTime as a key and the Value would be a new HashMap of GroupID and a list of Assignments of those that had the same groupName.
OutPut Example
HashMap<startTime,HasMap<groupName,List> hashMap = new HashMap();
a little more insight about the problem: First I want to categorise based on startTime(Month) then i want to categorise based on groupName, Thanks in advance.
I have successfully categorised based on group name and created a map through below code:
for( int i = 0; i<assignmentsdataArrayList.size();i++ ){
if (hashMap.size()>0){
hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}else {
hashMap.put(assignmentsdataArrayList.get(i).getGroupName(),new ArrayList<Assignmentsdata>());
hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}
}
After that I am lost on how to categorise this hashmap based on the startDate and create a hashmap that would look like the above hashmap in the output heading.
your code may throw a NullPointerException at the first if branch
if (hashMap.size()>0)
{hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}
the map.size()>0 doesnt means the Value of GroupName has put a new ArrayList already.
the anwser of using loop should like this
Map<String, Map<String, List<Assignmentsdata>>> map = new HashMap<>();
for (Assignmentsdata assignmentsdata : list) {
if (!map.containsKey(assignmentsdata.getStartTime())) {
map.put(assignmentsdata.getStartTime(), new HashMap<>());
}
Map<String, List<Assignmentsdata>> startTimeMap = map.get(assignmentsdata.startTime);
if (!startTimeMap.containsKey(assignmentsdata.getGroupName())) {
startTimeMap.put(assignmentsdata.getGroupName(), new ArrayList<>());
}
startTimeMap.get(assignmentsdata.groupName).add(assignmentsdata);
}
or you could use the java stream().collect(Collectors.groupingBy()) api to get the result easily
Map<String, Map<String, List<Assignmentsdata>>> result = list.stream()
.collect(Collectors.groupingBy(Assignmentsdata::getStartTime,Collectors.groupingBy(Assignmentsdata::getGroupName)));
I am answering my own question as I solved it if anyone has a better answer please passed your answer aswell, ill accept another answer suitable and efficient answer.
for( int i = 0; i<assignmentsdataArrayList.size();i++ ){
if (hashMap.size()>0){
if (hashMap.get(assignmentsdataArrayList.get(i).getGroupName())==null){
hashMap.put(assignmentsdataArrayList.get(i).getGroupName(),new ArrayList<Assignmentsdata>());
hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}else{
hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}
}else {
hashMap.put(assignmentsdataArrayList.get(i).getGroupName(),new ArrayList<Assignmentsdata>());
hashMap.get(assignmentsdataArrayList.get(i).getGroupName()).add(assignmentsdataArrayList.get(i));
}
}
// above part is already in the question. the second part i looped through the hashMap then the list once again, and checking if list and map entry have same group name, then made the startdate key that indexed element from the list.
HashMap<String, Map.Entry<String, ArrayList<Assignmentsdata>>> hashMapHashMap = new HashMap<>();
for (var entry : hashMap.entrySet()){
for( int j = 0; j<assignmentsdataArrayList.size();j++ ){
if (assignmentsdataArrayList.get(j).getGroupName()==entry.getKey()){
hashMapHashMap.put(assignmentsdataArrayList.get(j).getStartTime(),entry);
}
}
hashMapHashMap.put(entry.getValue().get())
}

Removing Keys from hashmap thru composite key value

Hey guys currently have problem with regards to removing duplicates from hashmap.
Some background:
My hashmap is in this format Map<CompositeKeyBean,ValueBean>.
CompositeKeyBean is in the form (String ID, String hashvalue);
ValueBean is an object.
So if i have a hashmap with values as such:
(ID:1,HashValue:123),Obj1
(ID:1,HashValue:234),Obj1
(ID:1,HashValue:345),Obj1
I need to remove the duplicate keys and only have items with unique IDs. currently I have come up with this, But it does not seem to work, im pretty sure i am doing something wrong.
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
for(int i = 1; i < list.size();i++)
{
if(list.keySet().contains(idvalue))
{
list.remove(i);
}
}
}
My solution for this one would be to declare first an another Map which will be used to hold the number of times that a certain key has appeared in the original Map. For the second time, you can iterate the same map entrySet and remove the duplicates using the declared additional Map as reference.
Map<String, Integer> numberOfInstanceMap = new HashMap<String, Integer>(); //temporary placeholder
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
if(!numberOfInstanceMap.containsKey(idvalue)) {
numberOfInstanceMap.put(idvalue, 1); //initialize the key to 1
} else {
numberOfInstanceMap.replace(idValue, numberOfInstanceMap.get(idValue) + 1); //add 1 to the existing value of the key
}
}
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
Integer i = numberOfInstanceMap.get(idValue);
if(i>1) { //remove duplicate if the key exists more than once
list.remove(idValue);
}
}
If you are expecting duplicate keys, then you can do the following way to handle it while populating the map itself:
Map<String, String> map = new HashMap<>();
if(map.containsKey("ID")){
String oldValue = map.get("ID");
//put logic to merge the value
}else{
map.put("ID","newValue");
}

Decrementing values from a randomized HashMap

The context here is context is in allocating meals to airline passengers.
Given a HashMap called allMealsList which is extracted from an API response and looks like this:
...I want to choose a meal at random, and return it so an adult passenger has a random meal. Don't worry about the conditional if("adult"), I am handling that elsewhere.
Where I am struggling is in decrementing the correct value from the HashMap.
My method is as follows:
public String chooseAvailableMeals(HashMap<String, Integer> allMealsList, String paxType) {
for (Iterator<Map.Entry<String, Integer>> it = allMealsList.entrySet().iterator(); it.hasNext(); ) {
Random generator = new Random();
Map.Entry<String, Integer> entry = it.next();
if (Objects.equals(paxType, "adult")) {
Object[] meals = allMealsList.keySet().toArray();
Object randomMeal = meals[generator.nextInt(meals.length)];
entry.setValue(entry.getValue() - 1);
return (String) randomMeal;
}
}
Where I do:
entry.setValue(entry.getValue() - 1);
It is, of course, decrementing not the value from the randomised key but of the first key - in this case "BBML".
Bear in mind I'm a relative java novice so I'm sure there is a more elegant or efficient way of doing this ;). Thank you in advance.
You don't need to iterate over the entries of the HashMap, just retrieve the relevant value by its key:
public String chooseAvailableMeals(HashMap<String, Integer> allMealsList, String paxType) {
Random generator = new Random();
if (Objects.equals(paxType, "adult")) {
Object[] meals = allMealsList.keySet().toArray();
Object randomMeal = meals[generator.nextInt(meals.length)];
Integer value = allMealsList.get(randomMeal);
if (value != null && value > 0) {
allMealsList.put(randomMeal, value - 1);
}
return (String) randomMeal;
}
// you should throw some exception or return some default value here
}
P.S. it would be better to create one Random instance outside of this method, and re-use it each time you need to generate a random number.

Contains operation in hashmap key

My hashmap contains one of entry as **key: its-site-of-origin-from-another-site##NOUN** and **value: its##ADJ site-of-origin-from-another-site##NOUN**
i want to get the value of this key on the basis of only key part of `"its-site-of-origin-from-another-site"``
If hashmap contains key like 'its-site-of-origin-from-another-site' then it should be first pick 'its' and then 'site-of-origin-from-another-sit' only not the part after '##'
No. It would be a String so it will pick up whatever after "##" as well. If you need value based on substring then you would have to iterate over the map like:
String value = map.get("its...");
if (value != null) {
//exact match for value
//use it
} else {//or use map or map which will reduce your search time but increase complexity
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getKey().startsWith("its...")) {
//that's the value i needed.
}
}
}
You can consider using a Patricia trie. It's a data structure like a TreeMap where the key is a String and any type of value. It's kind of optimal for storage because common string prefix between keys are shared, but the property which is interesting for your use case is that you can search for specific prefix and get a sorted view of the map entries.
Following is an example with Apache Common implementation.
import org.apache.commons.collections4.trie.PatriciaTrie;
public class TrieStuff {
public static void main(String[] args) {
// Build a Trie with String values (keys are always strings...)
PatriciaTrie<String> pat = new PatriciaTrie<>();
// put some key/value stuff with common prefixes
Random rnd = new Random();
String[] prefix = {"foo", "bar", "foobar", "fiz", "buz", "fizbuz"};
for (int i = 0; i < 100; i++) {
int r = rnd.nextInt(6);
String key = String.format("%s-%03d##whatever", prefix[r], i);
String value = String.format("%s##ADJ %03d##whatever", prefix[r], i);
pat.put(key, value);
}
// Search for all entries whose keys start with "fiz"
SortedMap<String, String> fiz = pat.prefixMap("fiz");
fiz.entrySet().stream().forEach(e -> System.out.println(e));
}
}
Prints all keys that start with "fiz" and sorted.
fiz-000##whatever
fiz-002##whatever
fiz-012##whatever
fiz-024##whatever
fiz-027##whatever
fiz-033##whatever
fiz-036##whatever
fiz-037##whatever
fiz-041##whatever
fiz-045##whatever
fiz-046##whatever
fiz-047##whatever
fizbuz-008##whatever
fizbuz-011##whatever
fizbuz-016##whatever
fizbuz-021##whatever
fizbuz-034##whatever
fizbuz-038##whatever

JAVA Iterateing through Hasmap with list

I need iterate through hashmap and get key value which should be a string and all values within that key which is a list of strings that have strings?
Psuedo code
static HashMap<String, List<String>> vertices = new HashMap<String, List<String>>();
for (int i = 0; i < vertices.size(); i++)
{
String key = vertices.getKey at first postions;
for (int x = 0; x < size of sublist of the particular key; x++)
{
String value = vertices key sublist.get value of sublist at (i);
}
}
You can't iterate over HashMap directly, as there is no numeric index of values within HashMap. Instead key values are used, in your case of type String. Therefore the values don't have a particular order. However, if you want, you can construct a set of entries and iterate over that, using vertices.entrySet().
for (Entry<String, List<String>> item : vertices.entrySet()) {
System.out.println("Vertex: " + item);
for (String subitem : item.getValue()) {
System.out.println(subitem);
}
}
Try vertices.keySet();
It gives a Set of all keys in the map. Use it in a for loop like below
for (String key : vertices.keySet()) {
for (String value : vertices.get(key)) {
//do stuff
}
}

Categories

Resources