I have a tag like this
public class AcsTag {
public static String getStyles(String paramter) {
return hashMap<String, String>()
}
}
}
I can access this tag in template (scala.html) like this
#import com.twago.fms.shared.ui.AcsTag
#AcsTag.getStyles(paramter)
getStyles method return a HasMap, I want to store that hashMap in a variable and then later get value from this hash map by key. I do want to iterate over map . I specifically want to access values by key.
following code i tried but always give error
"map not defined"
map =#{AcsTag.getStyles(paratmeter))}
#{map.get("themeColor")}
error "map not defined"
To declare a variable, you have to set at the top of your template:
#yourValue = #{yourExpression}
So, to declare a map value, you should do:
#map = #{AcsTag.getStyles(parameter)}
Then you'll be able to use yout map value anywhere in your template. Eg:
<div class="#map.get("themeColor")">...</div>
Related
I have the following piece of code which groups the given entries (activities, which is Iterable<activity>) based on IDs.
For the final result, I want it to return a Map of ID to Iterables of the entries grouped by that ID.
For example: Map<String, Iterables<activity>>.
Right now, it returns a Map<String, List<activity>>.
stream(activities)
.collect(
groupingBy(
activity -> {
if (activity.getID()) {
return activity.getID();
} else {
return activity.getName();
}
}));
I am unable to figure out a way to do this.
There's no such notion in Java as truthy values, which exists in languages like javascript. I.e. String can't be resolved into boolean automatically (what your code attempts to do).
There are multiple ways of how you can check whether the given value is null and provide an alternative value.
If name attribute is guaranteed to be non-null you can use static method requireNonNullElse() of the Objects utility class:
.collect(Collectors.groupingBy(act -> Objects.requireNonNullElse(act.getID(), act.getName()));
If name attribute is nullable, then you have to provide a default value that will be used in case if both id and name equal to null. Because null key is not allowed with Collectors.groupingBy() and will result in NullPointerException at runtime.
For the case when both field could be null I suggest extracting the logic for obtaining the key into a separate method.
public static String getKey(Action action) {
return action.getID() != null ? action.getID() :
action.getName() != null ? action.getName() : "defaultKey";
}
Which can be used inside the collector like that:
.collect(Collectors.groupingBy(act -> getKey(act)); // or as a method reference MyClass::getKey
Sidenote: by convention, names of classes in Java should start with a capital letter: Student, Employee, Activity.
so I have been able to put objects into my hash map successfully, but I'm having trouble returning an object. When I used an arrayList for this same project, I simply displayed it with the following method:
public void displayDetails(int currentItem) {
accountIDTextField.setText(table.get(currentItem).getAccountID()+"");
accountNumberTextField.setText(table.get(currentItem).getAccountNumber());
surnameTextField.setText(table.get(currentItem).getSurname());
accountTypeTextField.setText(table.get(currentItem).getAccountType());
}
And pressing the 'first' button would go to the number 1 in the list.
first.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentItem = 1;
displayDetails(currentItem);
}
});
As for my hashing, I have used the accountNumber as the key, (hashed by using the % modulo function)
Working backwards, I can get the accountID when I pass in the accountNumber as a parameter in the get() method.
hashMap.get(12345678).getAccountID();
But how do I return the accountID if I just want to get the first object stored in the hash map(i.e get accountID without knowing accountNumber)?
(AccountID is an integer unique to a particular account and will be automatically generated when a new account record is created)
Sorry if this isn't worded very well, I'm still trying to get my head around Java and OOP in general. Any help would be greatly appreciated. Thanks
hope I understood you right. getting only the first item of a HashMap would be something like:
Map<String, String> myhashmap = new HashMap<String, String>();
myhashmap.entrySet().iterator().next();
You can get the contents of the Map by using Map.values().
I would't access the value based on it's order in the map because ordering is not guaranteed. You should give each one a defined number. Then you can access them like:
Object o = map.values().get(id);
to get the first:
Object o = map.values().get(0);
I'm new to Java (and not too comfortable with strong typing) and I have a method that takes in a HashMap. A key in this hashmap contains a key, which has a hashmap for value, which also points to a hashmap, etc, until we reach a string:y
HashMap1->HashMap2->HashMap3->HashMap4->String
I am trying to access it as follows:
HashMap1
.get("aKey")
.get("anotherKey")
.get("yetAnotherKey")
.get("MyString");
But then I get an error,
Object does not have a method "get(String)
Here is the method, simplified:
public HashMap<String, HashMap> getMyString(Map<String, HashMap> hashMap1) {
String myString = hashMap1
.get("aKey")
.get("anotherKey")
.get("yetAnotherKey")
.get("MyString");
// do something with myString.
return hashMap1;
}
How would someone properly define the method and the parameters to access nested elements easily?
Thank you,
Simple as that
HashMap1.get("aKey") -- > return hashMap2
.get("anotherKey") --> return hashMap3
.get("yetAnotherKey") --> return hashMap4
.get("MyString"); --> return String
There is something wrong with the adding part.
Now you have structure like below.
hashmap1 --> hashmap2 --> String
String myString = hashMap1.get("aKey").get("MyString");
That is how it should be.
You made too many .get calls. Probably the last one is not needed.
Can you just create class CompoundKey with arbitrary number of String fields and use it as a key? It would simplify your design.
To use it properly in Java you need to override hashCode and equals methods.
You should first of all use interfaces not implementation, therefore use Map (and not HashMap) where possible.
And second, you should repair your Generics and use all levels. Now the compiler can help you and possible show your error.
// i suppose you want to return a String, at least the method name tells it
public String getMyString(Map<String, Map<String, Map<String, Map<String, String>>>> hashMap1) {
String myString = hashMap1
.get("aKey")
.get("anotherKey")
.get("yetAnotherKey")
.get("MyString");
return myString;
}
Yet i suggest that you use a different data structure.
I have a LinkedHashMap with a class as the Key as such:
private final Map<Files, String> list = new LinkedHashMap<Files,String>();
Files is a class consisting of 3 variables:
class Files {
public String file;
public String duration;
public String status;
}
Now I need to access the variables in Files using a index. I know that LinkedHashMap does not allow retrieving values using Index, so I tried this:
List<Entry<Files,String>> randAccess = new ArrayList<Entry<Files,String>>(list.entrySet());
Using randAccess.get(index) I can retrieve the Key itself, but not the specific variables inside the class. So the output is somethinglike Files#6aa91761=String.
I want to be able to get the variable, something like: list.Files.status.Get(index) would return return the value of "status" at the right Index.
You can get the Files variables from the Map.Entry using .getKey(). From there you can get the status field directly.
randAccess.get(index).getKey().status
in my action class i want to have a map of strings. and in my tml i want to access this map with textfield. something like
<t:form>
<t:textfield value="myMap['key1']"/>
<t:textfield value="myMap['key2']"/>
...
i don't insist on syntax, but is there anything like this currently in tapestry? if not, what do i need to create such conversion in the most easy way? type coercing? custom components? i'm starting to learn tapestry so feel free to be verbose :)
Another option is to bind your own tml prefix. There is an example of binding prefixes here.
We wrote our own prefix for map which allows us to get the value in the tml like this:
${map:myMap.key1}
ok, i figured it out. i did a simple component MapField:
#Parameter(required=true)
Map<String, String> map;
#Parameter(required=true, allowNull=false, defaultPrefix = BindingConstants.LITERAL)
String key;
public String getMapValue() {
return map.get(key);
}
public void setMapValue(String value) {
map.put(key, value);
}
tml:
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<t:textfield value="mapValue"/>
</html>
that's it. now we can use it in other tml:
<t:mapField key="existingOrNot" t:map="myMap"/>
and in a page we need only myMap as a property:
#Property #Persist Map<String, String> myMap;
probably there are more things to be done, like passing all additional html parameters to the textfield, etc
you will need to create an accessor method in your java class.
the most straightforward way would be to add a single method:
getMapValue(String key){...}
you can then change your tml to use
value="getMapValue('key1')"
You should be able to loop through the key set like this:
<form t:type="Form">
<t:Loop t:source="myMap.keySet()" t:value="currentKey">
<input type="text" t:type="Textfield" t:value="currentValue"/>
</t:Loop>
</form>
You'll have to add some code in the class file that stores the current map key and gives access to the current value:
#Property
private Object currentKey;
#Persist
#Property
private Map<String,String> myMap;
public String getCurrentValue() {
return this.myMap.get(this.currentKey);
}
public void setCurrentValue(final String currentValue) {
this.myMap.put(this.currentKey, currentValue);
}
(This answer is adapted from one of my earlier answers.)