I just want to ask why my HashMap is inserting the same value even if I put it inside a loop?
val parentMap = HashMap<String, Any?>()
val map = HashMap<String, Any?>()
orders.forEachIndexed { i, order ->
map["id"] = order.id
map["productName"] = order.productName
map["quantity"] = order.quantity
Log.i(TAG, "order=$order")
parentMap["data$i"] = map
Log.i(TAG, "map=$parentMap") // This parent map contains a same value from map...
}
Log.i(TAG, "map=$parentMap")
Did I forget something to put??
Any help is appreciated, Thanks.
So what you are doing here is assigning the map object to your parent map. The parent map stores the map object as a whole instead of the data. You will have to create a new 'map' object in every iteration.
I think "map" can be a reference variable. so it will insert the same values
To sum up what everyone said here.
In java and kotlin all objects stored in a heap and all your variables only store references to the objects in heap:
When you are doing this: parentMap["data$i"] = map
Your keys, ex: data1, data2, data3... will point to an instance of the same map which you created here: val map = HashMap<String, Any?>().
So everything that you do to your map:
map["id"] = order.id
map["productName"] = order.productName
map["quantity"] = order.quantity
change only one map that you have.
To fix it you can put your map creation inside the loop.
Or I suggest you to use immutable style like:
orders.mapIndexed { i, order ->
"data$i" to mapOf(
"id" to order.id,
"productName" to order.productName,
"quantity" to order.quantity
)
}.toMap()
You are creating the Map object outside the loop.
val map = HashMap()
So it will create single map entry where as you need different map for parent map.
Now you are entering different values in your map but since all maps references are now pointing to same Map Object so all Maps in your parent map will be showing last entries made to map.
The Solution is to keep val map = Hashmap() inside the loop. So with each iteration a different map objects will be created containg different data as per the iterations.
Related
I've got this structure of the database:
-requests
-userID
-requests
-requestingUserID1 : groupID1
-requestingUserID2 : groupID2
How to delete specific request by HashMap's key? Let's say I have some requestingUserID, and I want to delete it. So far I've got:
val updates = HashMap<String, Any>()
// updates["/requests/${firebaseUser.uid}/friendId"] = FieldValue.delete() // verion 1
updates["/requests/${firebaseUser.uid}/requests.${friendId}}"] = FieldValue.delete() //version 2
// more updates
db
.updateChildren(updates) // error occurs here
// onCompleteListener()
I get the following error:
com.google.firebase.database.DatabaseException: No properties to serialize found on class com.google.firebase.firestore.FieldValue$DeleteFieldValue
The simplest solution to delete a record from a Firebase Realtime Database is to use "removeValue()" method as shown in the following lines of code:
val rootRef = FirebaseDatabase.getInstance().getReference()
val friendIdRef = rootRef.child("requests/${firebaseUser.uid}/requests/${friendId}")
friendIdRef.removeValue().addOnCompleteListener(object : OnCompleteListener<Void?>() {
fun onComplete(task: Task<Void?>) {
if (task.isSuccessful()) {
Log.d(TAG, "Item successfully deleted.")
}
}
})
The delete() method that you are using is apart of the Firestore SDK. While both databases are apart of Firebase, both are two different products, with two different mechanisms.
Iterate over the HashMap using the Iterator.hasNext() method. While
iterating runs , check for the value at that iteration to be equal to
the value specified. The entry value of the Map can be obtained with
the help of entry.getValue() method. If the value matches, remove the
entry of that iteration from the HashMap using remove() method. The
required entry has been successfully removed.
I have mentioned a syntax below :
Iterator>
iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
if (valueToBeRemoved.equals(entry.getValue())) {
iterator.remove();
}
}
remove() method syntax is:
hashmap.remove(Object key, Object value);
Here, hashmap is an object of the HashMap class.
Remove method takes two types of parameter:
Key: remove the mapping specified.
Value : removes the mapping only if the specified key maps to the specified value.
How to add some value in ArrayList which is inside of HashMap? My bellow code showing 0 sizes of the hash
val hash= HashMap<String, ArrayList<String> >()
hash["bro"]?.add("Ali Umar")
hash["sis"]?.add("Tamanna")
hash["bro"]?.add("Faruk")
hash["sis"]?.add("Aklima")
hash["bro"]?.add("Ab Siddik")
Log.d("Hash", hash.size.toString())
You have to initialize a List and put the key and that initialized List into the HashMap before you can add any more items to the value of a key. In your example code nothing is put into the HashMap and nothing can be added.
Try it like this (or similar)
fun main() {
// initialize the hashmap
val hash = hashMapOf<String, MutableList<String>>()
// put the keys with empty lists into the hashmap
hash.put("bro", mutableListOf())
hash.put("sis", mutableListOf())
// add items to the value (the list) of existing keys
hash.get("bro")?.add("Ali Umar")
hash.get("sis")?.add("Tamanna")
hash.get("bro")?.add("Faruk")
hash.get("sis")?.add("Aklima")
hash.get("bro")?.add("Ab Siddik")
// print size and content
println("Hash size is ${hash.size.toString()}")
println(hash)
}
In the Kotlin Playground this outputs
Hash size is 2
{sis=[Tamanna, Aklima], bro=[Ali Umar, Faruk, Ab Siddik]}
The problem is that the following instructions are just reading from the hashmap but not inserting anything
hash["bro"]
hash["sis"]
so when you create your hashmap with val hash= HashMap<String, ArrayList<String> >() it is empty and "bro" and "sis" do not exist. so it is null and the add function will not be called because of ?. skips execution if the value is null.
so to add something to bro and sis you first have to put values to your hashmap.
hash.put("bro",ArrayList<String>())
hash.put("sis",ArrayList<String>())
this would change your example as follows
val hash= HashMap<String, ArrayList<String> >()
hash.put("bro",ArrayList<String>())
hash.put("sis",ArrayList<String>())
hash["bro"]?.add("Ali Umar")
hash["sis"]?.add("Tamanna")
hash["bro"]?.add("Faruk")
hash["sis"]?.add("Aklima")
hash["bro"]?.add("Ab Siddik")
Log.d("Hash", hash.size.toString())
HASH MAP
How to perform the addition when an hash map getting an input from the user
through the Edit text in android
final HashMap map = new HashMap<>();
map.put("input1", data1.getText().toString());
map.put("input2", data2.getText().toString());
map.put("input3", data3.getText().toString());
and i want to store and view the value in textview
I Didn't Get What you want
You have to convert that into Integers usingInteger.parseInt(data(x).getText.toString())
You can use HashMap.get() method
Do it with your own logic
I Guess It is Like this:
Integer Sum = ((map.get("input1")) + (map.get("input2")) + (map.get("input3")))
I have copied some code from a project and want to reuse a small part of it in my private app.
The class contains a Sparse Array
public class GolfResult {
String hcpAfter;
String hcpBefore;
SparseArray roundResults;
public GolfResult() {
hcpAfter = "";
hcpBefore = "";
roundResults = new SparseArray();
}
}
I have created an ArrayList for roundResults that is filled with the necessary data.
Then I am trying to fill the instance with content.
GolfResult golferRes = new GolfResult();
SparseArray<RoundResults> hu= new SparseArray<>();
hu = roundresults; // *
golferRes.setHcpAfter("33");
golferRes.setHcpBefore("kk");
golferRes.setRoundResults(hu);
But the problem is that hu = roudresults is not possible, because of the error message:
required: Android.util.SparseArray found: java.util.Array List
Any help will be welcome.
After receiving two helpful answers I got a step further, but now I am facing the problem that my SparseArray hu is empty {}.
The content of hu should be the class roundresults that has the following structure:
public class RoundResults {
boolean actualRound;
private List<HoleResult> holeResults;
Integer roundId;
Integer roundNumber;
String unfinishedReason;
The arrayList roundresults has the size of 1 and has data in the objects.
unfinishedReason =""
holeResults = ArrayLIST size= 18
roundID = "1"
roundNumber = "1"
actualRound = true
hu ={}
mValues = All elements are null
mSize = 0
Does anybody have an idea why?
SparseArray is different than ArrayList, from the documentation:
SparseArrays map integers to Objects. Unlike a normal array of
Objects, there can be gaps in the indices. It is intended to be more
memory efficient than using a HashMap to map Integers to Objects, both
because it avoids auto-boxing keys and its data structure doesn't rely
on an extra entry object for each mapping.
It's using a key value pair principle where the key is an integer and the value which the key mapping is the object. You need to use put [(int key, E value)](https://developer.android.com/reference/android/util/SparseArray.html#put(int, E)) where the E is your object. Remember that:
Adds a mapping from the specified key to the specified value,
replacing the previous mapping from the specified key if there was
one.
So you need to use a loop to add each object in your ArrayList as #valentino-s says:
SparseArray<RoundResults> hu= new SparseArray<>();
for( int i = 0; i < roundresults.size(); i++) {
// i as the key for the object.
hu.put(i, roundresults.get(i));
}
If I understand well your problem, maybe you can try with this:
for ( int i=0; i<roundresults.size(); i++ ) {
hu.put(i,roundresults.get(i));
}
After some trial and error I found a solution for the empty hu:
Instead of put I used append and it is working now.
hu.append(i, roundresults.get(i));
Time for a beer.
I am displaying list of check-boxes in horizontal RecyclerView.
It display values such as {"Rd" , "Gr" , "Yl"} but when user selects any of this value it should return {"RED" , "GREEN" , "YELLOW")
How can I bind these two value that show and return differently?
I am taking display values from R.string-arry
I created another string-array of actual values, and when user checked any of checkboxes I get that ID and replaced it with actual values.
For e.g. If user has selected "Gr" I get ID=1 then replaced with actual string-array
But this only works when code-color and original-color are in order. In my app I sometimes use Red,green,blue or sometimes green,yellow,blue. So, this won't help me.
From what I understood, you need a mapping between GR and Green, RD and Red etc.
You can try using a Hashmap.
HashMap<String,String> colourMap = new HashMap<>();
colourMap.put("GR","GREEN");
colourMap.put("RD","RED");
And then you can retrieve the respective value for your colour code:
String colour = colourMap.get("GR");
You can use a HashMap which will bind the two arrays as key value pair
public HashMap<String,String> bindColors() {
HashMap<String,String> map = new HashMap<>();
int length = orginalColors.length;
for (int i = 0; i < length; i++) {
map.put(orginalColors[i], codeColors[i]);
}
return map;
}
And for getting the Colors in code.
HashMap<String, String> keyPair = bindColors();
orginalColorsNewArray = keyPair.keySet().toArray(new String[keyPair.keySet().size()]);
codeColorsNewArray = keyPair.values().toArray(new String[keyPair.values().size()]);
or use .get() function
keyPair.get("YELLOW")
Now it will be easier for you to access the codes by id/position
Hope this helps.