This question already has answers here:
Why initialize the key of extra?
(4 answers)
Closed 9 years ago.
Our intents carry data from one activity to another by key value pairs called extras.
We initialize the key (i.e. declare it as a constant and assign it something e.g. public static final String mykey= "something";) before passing it to the intent by using intent.putExtra(mykey, myvalue);
My question is why do we need to assign a value to the key when it is being declared? What is the use of that value? What is the use of ' = "something" ' in public static final String mykey= "something";
I posted a related question, and a respected person (respected because of their valuable answers) said that when a final is declared, a value must be assigned so it is known what the constant is. Sounds like common sense.
But if I simply declare a constant public static final String a; the compiler does not complain at all, which means initializing a final variable with a value is not a must, as long as it is initialized before it is used.
A relevant answer is appreciated. Thank you in advance.
I'm assuming an Intent is backed by a Map.
If you would have an uninitialized variable as the key, this would mean that the value is essentially lost: there's no way of retrieving it since there's no key associated with it (although I believe it might not be possible at all to insert a null key in a map).
You don't have to actually assign this key to a variable: intent.putExtra("somekey", somevalue); works just as fine.
It's just a matter of making sure you don't accidentally use the wrong key.
As an illustration of why it is beneficial to use final variables:
public static void main(String[] args) {
Map<String, Integer> someMap = new HashMap<>();
String theValue = "X";
someMap.put(theValue, 5);
System.out.println("Variable: " + theValue);
System.out.println("Map: " + someMap.get(theValue));
theValue = "Y";
System.out.println("Variable: " + theValue);
System.out.println("Map: " + someMap.get(theValue));
System.out.println("ByValue: " + someMap.get("X"));
}
Output:
Variable: X
Map: 5
Variable: Y
Map: null
ByValue: 5
If theValue would be final, it wouldn't be able to be reassigned and there wouldn't be any problems getting the value from the underlying Map.
Related
I'm wondering if it's possible to store a partial View ID in a variable.
For example: If I would have two Views, one with the ID food_pizza and a second one with the id food_burger, could I store "pizza" and "burger" in a variable as a string and then access both Views through R.id.("food_" + VARIABLE) and R.id.("food_" + VARIABLE).
Thanks in advance! :)
Don't know why you would want to do it, but here you go :)
int id = getResources().getIdentifier("food_" + VARIABLE, "id", getPackageName());
Not possible like this R.id.("food_" + VARIABLE)
You can try this alternative way:
Create HashMap<String, Integer> ids = new HashMap<>();
Then add ids to map with keys like food_pizza etc
ids.put("food_pizza", R.id.food_pizza);
ids.put("food_burger", R.id.food_burger);
and to use it you get ids like findViewById(ids.get("food_" + VARIABLE));
Updating a field contains period (.) is not working as expected.
In docs, nested fields can be updated by providing dot-seperated filed path strings or by providing FieldPath objects.
So if I have a field and it's key is "com.example.android" how I can update this field (from Android)?
In my scenario I've to set the document if it's not exists otherwise update the document. So first set is creating filed contains periods like above and then trying update same field it's creating new field with nested fields because it contains periods.
db.collection(id).document(uid).update(pkg, score)
What you want to do is possible:
FieldPath field = FieldPath.of("com.example.android");
db.collection(collection).document(id).update(field, value);
This is happening because the . (dot) symbol is used as a separator between objects that exist within Cloud Firestore documents. That's why you have this behaviour. To solve this, please avoid using the . symbol inside the key of the object. So in order to solve this, you need to change the way you are setting that key. So please change the following key:
com.example.android
with
com_example_android
And you'll be able to update your property without any issue. This can be done in a very simple way, by encoding the key when you are adding data to the database. So please use the following method to encode the key:
private String encodeKey(String key) {
return key.replace(".", "_");
}
And this method, to decode the key:
private String decodeKey(String key) {
return key.replace("_", ".");
}
Edit:
Acording to your comment, if you have a key that looks like this:
com.social.game_1
This case can be solved in a very simple way, by encoding/decoding the key twice. First econde the _ to #, second encode . to _. When decoding, first decode _ to . and second, decode # to _. Let's take a very simple example:
String s = "com.social.game_1";
String s1 = encodeKeyOne(s);
String s2 = encodeKeyTwo(s1);
System.out.println(s2);
String s3 = decodeKeyOne(s2);
String s4 = decodeKeyTwo(s3);
System.out.println(s4);
Here are the corresponding methods:
private static String encodeKeyOne(String key) {
return key.replace("_", "#");
}
private static String encodeKeyTwo(String key) {
return key.replace(".", "_");
}
private static String decodeKeyOne(String key) {
return key.replace("_", ".");
}
private static String decodeKeyTwo(String key) {
return key.replace("#", "_");
}
The output will be:
com_social_game#1
com.social.game_1 //The exact same String as the initial one
But note, this is only an example, you can encode/decode this key according to the use-case of your app. This a very common practice when it comes to encoding/decoding strings.
Best way to overcome this behavior is to use the set method with a merge: true parameter.
Example:
db.collection(id).document(uid).set(new HashMap<>() {{
put(pkg, score);
}}, SetOptions.merge())
for the js version
firestore schema:
cars: {
toyota.rav4: $25k
}
js code
const price = '$25k'
const model = 'toyota.rav4'
const field = new firebase.firestore.FieldPath('cars', model)
return await firebase
.firestore()
.collection('teams')
.doc(teamId)
.update(field, price)
Key should not contains periods (.), since it's conflicting with nested fields. An ideal solution is don't make keys are dynamic, those can not be determined. Then you have full control over how the keys should be.
I am trying to use a NumberPicker to display an array of Strings, but when I try and get the value back of the current String, the value is the integer index value of the String within the array which is the default response.
I have been trying to use NumberPicker.Formatter to get the actual String as a value back as opposed to the integer index value. I have implemented this, but it doesn't seem to be invoked. Could someone please tell me why this is and what I can do to fix it. Thanks in advance.
Here is the code:
final NumberPicker npUnits = (NumberPicker) numberPickerView.findViewById(R.id.numberPicker2);
npUnits.setMinValue(1);
npUnits.setDisplayedValues(tableUnitsArray);
npUnits.setMaxValue(tableUnitsArray.length);
npUnits.setFormatter(new NumberPicker.Formatter()
{
#Override
public String format(int value)
{
ArrayList<String> stringArrayList = (ArrayList<String>) Arrays.asList(tableUnitsArray);
String defaultUnits = stringArrayList.get(value);
System.out.println("Value formatted result: " + defaultUnits);
return defaultUnits;
}
});
npUnits.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
NumberPicker allows you to pick your values based on the min and max values you specify. It does not need you to call setDisplayedValues(). NumberPicker uses the String array you specify as a set of alternate values which causes your formatter to be ignored. Try removing the call to setDisplayedValues().
If your values for your NumberPicker are not so straight forward (i.e not from min to max incrementing by 1), then you can transform your values in your formatter to get the desired number.
I have found out the answer to my question. NumberPicker.Formatter was the wrong thing that I was doing as I didn't actually need to format anything. I just needed to get the current value from the String[] displayed values.
This is the code that worked for me:
List<String> stringArrayList = (List<String>) Arrays.asList(npUnits.getDisplayedValues());
String defaultUnits = stringArrayList.get(npUnits.getValue() - 1);
I found a solution for a few bugs in NumberPicker that works in APIs 18-26 without using reflection and without using setDisplayedValues() here.
I have a string where I have a value: 2,6. How can I change "," on "." I use x.replace(",", "."); but doesn't work. This is any other method to do that?
Try using:
x = x.replace(",",".");
In Java, Strings are immutable, so you will always get a new String from the operations. You have to store this new String, or your changes are lost. replace() returns a new String object, so you need to keep a reference to this new object. Your older String is not modified.
String is immutable it create the new object again after modifying in string. So You need to assign the result.
Do like this.
x= x.replace(",", ".");
Correct way is:
x = x.replace(",", ".");
String is immutable, it can't be changed. x.replace creates a new string
Is is possible to create an new local variable from value of another?
e.g. if value of var1 = "button1" can I construct a new local variable like button1type, ie.using the value of var1 to make part of the new variable
Like this?
String foo = "ohai_" + var1; // Would be "ohai_button1"
If you mean name the variable based on the value in var1? No, but you don't need to.
If you need to associate data based on a string (or other) value, consider using a map.