Adding value to list object in hash-map - java

I'm trying to add list object to hashmap
I tried with the following code didn't worked
public static Map<Long, List<Long>> getCellAttributes(List<Vo> voList){
LOG.info("VO: {}", Arrays.toString(VO.toArray()));
Map<Long, List<Long>> atributesMap = new HashMap();
List<Long> cellList = new ArrayList<>();
for(: VOList){
Long cID = VO.getID();
Long cellUserNumber = VO.getCellNumber();
if(cellMap.containsKey(ID)){
cellList.add(cellNumber);
cellmap.put(ID, list);
}
else {
Map.put(ID, cellAtributesMap.get(ID).add(cellNumber));
}
}
return cellMao;
}
Found below error for else block part.
Wrong 2nd argument type. Found: 'boolean', required:

Ok, first off, what is Map.put in the else block? To me it sounds wrong logically, probably you meant the case where the campaignId is not in the map yet.
In this case, you can just:
else {
List<Long> cellList = new ArrayList<>();
cellList.add(cellUserNumber);
cellAtributesMap.put(campaignId, cellList);
}
Now the if block also looks logically wrong, there is no need to maintain a global list (what if the targetedOffersCampaignVOList is not ordered) and there is no need to put every time into the map.
Since it doesn't seem to be a homework for me, here is a better version:
Map<Long, List<Long>> cellAtributesMap = new HashMap();
// note, the following line is not required and should be removed
//List<Long> cellList = new ArrayList<>();
for(TargetedOffersCampaignVO targetedOffersCampaignVO: targetedOffersCampaignVOList){
Long campaignId = targetedOffersCampaignVO.getCampaignID();
Long cellUserNumber = targetedOffersCampaignVO.getCellUserNumber();
if(cellAtributesMap.containsKey(campaignId)){
// the list in the value already exists anyway, just add a new cell user number to it
cellAttributesMap.get(campaignId).add(cellUserNumber);
}
else {
// create a new key-value pair in the result map
// and add one element which is a current cellUserNumber to it
List<Long> cellList = new ArrayList<>();
cellList.add(cellUserNumber);
cellAtributesMap.put(campaignId, cellList);
}
}
return cellAtributesMap;

I think you have problem in your else block:
else {
Map.put(campaignId, cellAtributesMap.get(campaignId).add(cellUserNumber));
}
Map call here is in inappropirate. If my guess is correct, you want to initialize a new array if that particular campaignId does not exist in previously, in that case you want to execute this else block. Then you just change your else block like this:
else
{
List<Long> newList= new ArrayList<>();
newList.add(cellUserNumber);
cellAtributesMap.put("campaignId", newList);
}

cellAtributesMap.get(campaignId).add(cellUserNumber)
Above method call returns a boolean value.
Your else block should be like below
List<Long> list=new ArrayList<>();//any list implementation
list.add(cellUserNumber);
cellAtributesMap.put(campaignId,list);

Related

How can I make a new HashMap that won't change the one I've copied from?

I have a HashMap called the Item Database, which stores data about all of the items.
However, these items can have modifiers (in this case, the stat multiplier is important). Whenever I change an item to just one specific item drop, it ends up changing the base item from the HashMap.
For example, whenever a player creates a Katana, it does something like this.
HashMap<String, CustomItem> db = new HashMap<String, CustomItem>();
db.putAll(ItemDatabase.database);
CustomItem ci = db.get("KATANA");
From there, modifiers are applied via a getBukkitItem function on the CustomItem ci, basically multiplying a lot of the stats on that CustomItem and applying it.
baseHealth = (int) ((abbaseHealth / 100.0) * multiplier);
and other stats like that.
However, whenever I make changes to this new CustomItem, it also applies to the ItemDatabase hashmap. This means that whenever somebody makes another Katana, those multiplied stats become the new base stats to be multiplied.
TL;DR Whenever I'm changing a variable I got from a HashMap (db), that change also applies to the HashMap (itemdb). This happens even if the HashMap (db) it's from, is a copy of another HashMap (itemdb)
I have tried the method above, and using .clone() on a HashMap and casting it back to HashMap. Unfortunately I'm not really sure what else to try.
you should create a new object of deep clone. Using orika framework like below.
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
#Test
public void t() {
Map<Integer, User> map = new HashMap<>();
User one = new User();
one.setName("one");
System.out.println(one);
User two = new User();
two.setName("two");
System.out.println(two);
map.put(1,one);
map.put(2,two);
TypeBuilder<Map<Integer,User>> typeBuilder = new TypeBuilder<Map<Integer,User>>() {
};
Type<Map<Integer,User>> type = typeBuilder.build();
Map<Integer,User> copyMap = mapperFactory.getMapperFacade().mapAsMap(map, type,type);
System.out.println(copyMap.get(1));
System.out.println(copyMap.get(2));
}
You need to make new CustomItem instances. If you only make a copy of the Map, you’re just copying the references stored in the Map; they’ll still refer to the same CustomItem instances.
You can make this easier by adding a copy constructor or clone() method to CustomItem. Example of a copy constructor:
public class CustomItem {
public CustomItem(CustomItem other) {
this.name = other.name;
this.baseHealth = other.baseHealth;
this.multiplier = other.multiplier;
// Don't want two instances to refer to the same List!
this.inventoryList = new ArrayList<>(other.inventoryList);
// etc.
}
}
Example of a clone() method:
public class CustomItem
implements Cloneable {
#Override
public CustomItem clone()() {
try {
CustomItem copy = (CustomItem) super.clone();
// Don't want two instances to refer to the same List!
copy.inventoryList = new ArrayList<>(copy.inventoryList);
// etc.
return copy;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
Once you have a way to copy CustomItem instances, you need to use it in your new Map:
Map<String, CustomItem> newMap = new HashMap<>();
for (Map.Entry<String, CustomItem> entry : db) {
String key = entry.getKey();
CustomItem value = entry.getValue()
value = value.clone();
newMap.put(key, value);
}
A shorter way:
Map<String, CustomItem> newMap = new HashMap<>(db);
newMap.replaceAll((k, v) -> v.clone());

How to add an item to list inner hashmap?

HashMap<String, List<Person.Personal>> hashMap = new HashMap();
var attachment = new Person.Personal(name, surname, birthDate);
I need to add item with key that comes from another map.
Then I need the code like below;
if(hashMap.containsKey(courseGroup.getKey().get(0)))
{
hashMap.put(courseGroup.getKey().get(0), attachment);
}
else
{
hashMap.put(courseGroup.getKey().get(0), new Arraylist<Person.Personal> (attachment));
}
This code show error:
Cannot resolve constructor 'Arraylist(Person.Personal)'
If the hashmap has the key then add its value list "attachment", if has not, create a list then add "attachment", I need.
if(hashMap.containsKey(courseGroup.getKey().get(0)))
{
hashMap.get(courseGroup.getKey().get(0)).add(attachment);
}
else
{
List<Person.Personal> list = new ArrayList<>();
list.add(attachment);
hashMap.put(courseGroup.getKey().get(0), list);
}
These lines solved my issue.
As the arraylist already exists instead of putting it again use updating the arraylist.
For example:
if(hashMap.containsKey(courseGroup.getKey().get(0)))
{
// adding values directly to the arraylist.
hashMap.get(courseGroup.getKey().get(0)).add(attachment);
}
else
{
List<Person.Personal> list= new Arraylist<> ();
list.add(attachment);
// create a new array and put it there.
hashMap.put(courseGroup.getKey().get(0), list);
}

Method put() in java Map of type <<String>,List<String>>

How can I put in a map of above type. I do not want to overwrite existing mapping.
So far my code is:
public class Store {
Map<String, List<String>> items;
public Store(){
items = new HashMap<String, List<String>>();
}
public boolean containsKey(String key) {
return items.containsKey(key);
}
public void put(String key, String item) {
List<String> myList = new ArrayList<>();
if (myList == null) {
myList = new ArrayList<String>();
items.put(key, item);
}
}
}
I stopped here because I received an error message stating "change the item type to list String from String". I can not figure out if I am doing something wrong.
Here, double wrong:
List<String> myList = new ArrayList<>();
if (myList == null) {
myList = new ArrayList<String>();
items.put(key, item);
}
myList will never be null, you just assigned a list to it! And item is just a single string, so you shouldn't use it as value for a map that expects lists of strings as value!
You go:
List<String> myList = items.get(key);
if (myList == null) {
myList = new ArrayList<String>();
}
myList.add(item);
items.put(key, myList);
instead.
Meaning: first you check if you already have a list for that key. If not, you create an empty one. Then you add your new item to the (potentially new) list. Before finally putting the list into the map (it could be already there, but then you just overwrite that information with "itself").
And if you want to know how the "pros" solve this problem, have a look at this questions and the answers I received upon asking it.
Or use Map.computeIfAbsent() that is designed for this requirement : add a new entry if not existing mapping for a specific key and getting the value for (the new one or the existing) :
items.computeIfAbsent(key, k -> new ArrayList<>())
.add(item);

How can I can check if a value exists in an ArrayList?

try {
List<UpdateStockModel>
stockistIds=updateStockMapper.getStockInvoiceId(stockmodel);
String myList = new String();
for (UpdateStockModel x : stockistIds) {
//System.out.println("stockist list id.." + x.getStockInvoiceIds());
myList = myList.concat(x.getStockInvoiceIds());
myList = myList.concat(",");
}
List<String> list = new ArrayList<String>();
list.add(myList);
System.out.println("list.." + list);
System.out.println("stockInvoiceId is.." +
stockmodel.getStockInvoiceIds());
System.out.println("list status.." +list.contains(stockmodel.getStockInvoiceIds()));
if (list.contains(stockmodel.getStockInvoiceIds()) ==true){
return true;
} else {
return true;
}
}
Output:
list..[47,49,50,51,52,53,54,55,56,57,58,59,60,62,64,65,66,67,68,69,70,71,72,74,75,]
stockInvoiceId is..66
list status..false
return else
Here 66 existed in list but return false.I need to get true
Okay lets get it straight here.
You got a List full of objects which contain a ID.
You get the IDs from the object and concate them to a single large String.
Later on you add this single String to an ArrayList and expect the List.contains() method to find a proper match for you. This is not how it works.
You can either fix this, by calling list.get(0).contains(...) which will work since you will retrieve your string from the list and check it for the ID or even better,you add the Strings themself to an ArrayList.
Doing so would end up similiar to this:
List<UpdateStockModel>
stockistIds=updateStockMapper.getStockInvoiceId(stockmodel);
List<String> myList = new ArrayList<>();
for (UpdateStockModel x : stockistIds) {
myList.add(x.getStockInvoiceIds());
}
Doing so will replace the following part:
//This all becomes useless since you will already have a list with proper objects.
List<String> list = new ArrayList<String>();
list.add(myList);
System.out.println("list.." + list);
System.out.println("stockInvoiceId is.." +
stockmodel.getStockInvoiceIds());
System.out.println("list status.." +list.contains(stockmodel.getStockInvoiceIds()));
It's not rocket science.
Think of Lists as they were just more dynamic and flexible Arrays.
I think this is what you're after:
Set<String> ids = updateStockMapper.getStockInvoiceId(stockmodel)
.stream()
.map(usm -> usm.getStockInvoiceIds())
.collect(Collectors.toSet());
String id = stockmodel.getStockInvoiceIds();
return ids.contains(id);
Try to initalize the list as follows:
List<String> list = new ArrayList<String>();
for (UpdateStockModel x : stockistIds) {
//System.out.println("stockist list id.." + x.getStockInvoiceIds());
list.add(x.getStockInvoiceIds());
}
Then you can compare agains a list and not against a String.
// if the element that you want to check is of string type
String value= "66";// you use element instead of 66
Boolean flag=false;
if (list.contains(value)){
flag=true;
} else {
flag=false;
}
//you can use flag where you want
It looks like you setup the list varible as as an Arry with one entry.
replacing the statement
list.contains(..)
with
stockistIds.contains(..)
should do the trick.
The problem is in the if statement
Change:
if (list.contains(stockmodel.getStockInvoiceIds()) ==true){
return true;
} else {
return true;
}
to:
if (list.contains(stockmodel.getStockInvoiceIds()) ==true){
return true;
} else {
return false;
}

TreeMap using a string key and an arraylist

I am brand new to using collections, so I am confused on how to do this. I am trying to use a TreeMap to hold a word as the key and then an ArrayList to hold one or more definitions for the word.
public class Dict {
Map<String, ArrayList<String>> dic = new TreeMap<String, ArrayList<String>>();
public void AddCmd(String word, String def) {
System.out.println("Add Cmd " + word);
if(dic.get(word)==null){
dic.put(word, new ArrayList.add(def));
}
}
}
I am getting an error on "new ArrayList.add(def)". I thought this was the correct way to do this, but I am obviously wrong. Does anyone have any ideas as to what I am doing wrong?
Calling ArrayList#add returns a boolean which is not the desired value for your Map, thus getting the compiler error.
You need to insert the ArrayList and then add the element. Your code should look like this:
ArrayList<String> definitions = dic.get(word);
if (definitions == null) {
definitions = new ArrayList<String>();
dic.put(word, definitions);
}
definitions.add(def);
dic.put(word, new ArrayList.add(def)); is the culprit.
since you have declared map to take Arraylist of string as a value. the value to pass for map must be Arraylist of string.
but this line is adding a value as new ArrayList.add(def) since you are trying to create a list and adding element , add method returns boolean -> true if it can add false if it fails.
so it means value to the map is going as a boolean not as arraylist which is against the map declaration.
so use code as below
ArrayList<String> listOfString = dic.get(word);
if (listOfString == null) {
listOfString = new ArrayList<String>();
listOfString .add(def);
}
dic.put(word, listOfString );
You have to break it up, because add does not return the original ArrayList:
ArrayList<String>> NewList = new ArrayList<String>();
NewList.add(def);
dic.put(word, NewList);
You are not actually creating a new ArrayList. Try this:
ArrayList<String> newDef = new ArrayList<String();
newDef.add(def);
dic.put(word, newDef);

Categories