Populate ComboBox with HashMap? - java

I'm trying populate a combobox of vaadin7 with informations hashmap. I create a class that return a HashMap when I get the return I use a for each to populate this combobox but does show me only numbers and not the keys and values of hashmap.
I'm trying this.
/** states of brasil class */
public class EstadosBrasil {
private static final HashMap<String, String> uf = new HashMap();
/** return all states of brasil */
public static HashMap<String, String> getEstados(){
uf.put("AC", "AC");
uf.put("AL", "AL");
uf.put("AM", "AM");
uf.put("AP", "AP");
uf.put("BA", "BA");
uf.put("CE", "CE");
uf.put("DF", "DF");
uf.put("ES", "ES");
uf.put("FN", "FN");
uf.put("GO", "GO");
uf.put("MA", "MA");
uf.put("MG", "MG");
uf.put("MS", "MS");
uf.put("MT", "MT");
uf.put("PA", "PA");
uf.put("PB", "PB");
uf.put("PE", "PE");
uf.put("PI", "PI");
uf.put("PR", "PR");
uf.put("RJ", "RJ");
uf.put("RN", "RN");
uf.put("RO", "RO");
uf.put("RR", "RR");
uf.put("RS", "RS");
uf.put("SC", "SC");
uf.put("SE", "SE");
uf.put("SP", "SP");
uf.put("TO", "TO");
return uf;
}
}
// my combobox
private ComboBox comboEstado;
comboEstado = new ComboBox("States");
comboEstado.setWidth("100px");
HashMap<String, String> estados = EstadosBrasil.getEstados();
for(Entry<String, String> e : estados.entrySet()){
Object obj = comboEstado.addItem();
comboEstado.setItemCaption(e.getKey(), e.getValue());
comboEstado.setValue(obj);
}
mainLayout.addComponent(comboEstado);
Any idea ?
thanks

Change-
Object obj = comboEstado.addItem();
comboEstado.setItemCaption(e.getKey(), e.getValue());
comboEstado.setValue(obj);
To-
comboEstado.addItem(e.getKey());
comboEstado.setItemCaption(e.getKey(), e.getValue());
If you want both key and value pair to appear, something like this can be done-
comboEstado.setItemCaption(e.getKey(), e.getKey() + " : " + e.getValue());
By the way, I hope you are going to change the values. If both key and value are the same, you can just use a Set.

In the new Vaadin 8 API, there is no addItems method on Combobox.
The code below works:
Map<String, String> map = new HashMap<>();
ComboBox combobox = new ComboBox<>("My Combobox");
combobox.setItems(map);
combobox.setItemCaptionGenerator(new ItemCaptionGenerator() {
#Override
public String apply(Object o) {
HashMap m = (HashMap) o;
return m.keySet().stream().findFirst().get().toString();
}
});

Related

JSF / Xpages how to clear sessionscopes?

I want to clear the current sessionscopes in my xpages application and reload them again. I have tried:
public Map<String, Object> sesScope;
this.sesScope = JSFUtil.getSessionScope();
clearMap(sesScope);
private void clearMap(Map<String, Object> map ){ // Get iterator for the keys
String methodName = new Object(){}.getClass().getEnclosingMethod().getName();
utils.printToConsole(this.getClass().getSimpleName().toString() + " " + methodName);
utils.printToConsole("-------before removing------");
utils.printToConsole(map.toString());
Set keyset = map.keySet();
Iterator itr = keyset.iterator();
while (itr.hasNext()) {
itr.next();
itr.remove();
}
utils.printToConsole("--------After removing-------");
utils.printToConsole(map.toString());
}
Somehow I can not simply say sesScope.clear() since that would result in an error:
java.lang.UnsupportedOperationException at
com.sun.faces.context.BaseContextMap.clear(ExternalContextImpl.java:392)
How do I clear the sessionscope properly?
I do this to clear sessionScope:
for (final String key : JSFUtil.getSessionScope().keySet()) {
JSFUtil.getSessionScope().remove(key);
}

Java - SnakeYaml | Get all keys of a file

First of all, I have been reading a few posts about keys, but none of them asks my question on how to get ALL keys of a yaml file, only on how to get an specific key.
Now, I want to create a file updater, it works, but it only updates the first keys, without the "sub-keys", here is the code:
InputStream resource = getClass().getClassLoader().getResourceAsStream(dir);
Map<String, Object> data = new Yaml().load(resource);
for(String str : data.keySet()) {
DBot.getConsole().log(str);
if(!contains(str)) {
set(str, data.get(str));
}
}
The file looks like this:
Features.Example.StringA
Features.Example.StringB
With points being spaces to make them sub-keys (stack overflow puts them on a single line, sorry)
Now the thing is, the updater will only work if "Features" is deleted, also, the debug will only print "Features", meaning that only the first key is on the key set, how can I get all keys?
I have finally found how to return a Set with every key separated by a ".", Bukkit/Spigot developers might be familiar with this. First of all, you have to create a class like this:
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class YamlKeys {
private static Set<String> keys = new HashSet<String>();
private static String path = "";
YamlKeys(Map<?, ?> data) {
getKeysRecursive(data);
}
private void getKeysRecursive(final Map<?, ?> data) {
for(Object key : data.keySet()) {
final Object value = data.get(key);
if(key instanceof String) {
if(path.length() == 0) {
path = (String)key; // If the key is the first on the path, don't include separator.
} else {
path = path+"."+(String)key; // Here is the separator, you can change it.
}
}
if(value instanceof Map) {
getKeysRecursive((Map<?, ?>) value); // A value map has been found, recursing with that value.
} else {
keys.add(path); // No more maps have been found, we can add the path and stop recursing.
if(path.contains(".")) {
path = path.substring(0, path.lastIndexOf(".")); // Removing last key, so if a value contains more than one key, it won't appear again.
}
}
}
path = ""; // This is important, reset the path.
}
Set<String> getKeys() {
return keys;
}
}
Then, to call it and select if you want to get deep keys or "normal" keys, you can create a method like this:
public Set<String> getKeys(boolean deep) {
Map<String, Object> data = new Yaml().load(inStream);
if(!deep) {
return data.keySet();
} else {
return new YamlKeys(data).getKeys();
}
}
To test it, we can use the following code:
new YamlKeys(data).getKeys().stream().forEach(key -> System.out.println(key));
With this file:
FirstKey:
SecondKey:
Enabled: true
Text: "Some text"
AnotherKey:
AValue: true
AnotherTest:
Enabled: false
Value: true
It returns this output:
FirstKey.SecondKey.AnotherKey.AValue
FirstKey.SecondKey.Enabled
FirstKey.SecondKey.Text
Value
AnotherTest.Enabled
Thanks to roby for telling me about recursion.
SnakeYAML is decoding the yaml into a recursive data structure. For example:
public static void main(String[] args) {
String yaml = "a:\n b: \n c: \"string\"";
Map<String, Object> data = new Yaml().load(yaml);
System.out.println(data);
}
prints out:
{a={b={c=string}}}
Which is a Map<String, Map<String, Map<String, String>>>.
To show how you can work with it recursively, here's how you can print out some of that detail.
private static void printMapRecursive(final Map<?, ?> data) {
for(Object key : data.keySet()) {
System.out.println("key " + key + " is type " + key.getClass().getSimpleName());
final Object value = data.get(key);
if(value instanceof Map){
System.out.println("value for " + key + " is a Map - recursing");
printMapRecursive((Map<?, ?>) value);
} else {
System.out.println("value " + value + " for " + key + " is type " + value.getClass());
}
}
}
Which you can call with printMapRecursive(data); and see output:
key a is type String
value for a is a Map - recursing
key b is type String
value for b is a Map - recursing
key c is type String
value string for c is type class java.lang.String
and an example of recursively transforming the keys:
private static Map<?, ?> mutateMapRecursive(final Map<?, ?> data,
Function<String, String> keyFunction) {
Map<Object, Object> result = new HashMap<>();
for (Object key : data.keySet()) {
final Object value = data.get(key);
if(key instanceof String){
key = keyFunction.apply((String) key);
}
if (value instanceof Map) {
result.put(key, mutateMapRecursive((Map<?, ?>) value, keyFunction));
}
else {
result.put(key, value);
}
}
return result;
}
called like:
final Map<?, ?> transformed = mutateMapRecursive(data, (key) -> "prefix_" + key);
System.out.println(transformed);
emits:
{prefix_a={prefix_b={prefix_c=string}}}

Compare two arraylists to return the latest date

I have two arraylists as follows.
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1","1","1","2","2","3");
values.add("2016-06-22 07:18:45", "2016-06-22 08:18:45", "2016-06-22 09:18:45",
"2016-06-22 03:18:45","2016-06-22 04:18:45","2016-06-22 01:18:45");
Now i need the function
HashMap latestValues(keys, values);
The output should be as follows,
["1"=>"2016-06-22 09:18:45","2"=>"2016-06-22 04:18:45", "3"=>"2016-06-22 01:18:45"]
Returning the latest dated single value for that particular key. Can anyone please suggest how to achieve this.
Thanks and advance!
I think this will do it.
public static void main(String[] args) {
ArrayList<String> keys = new ArrayList<>(Arrays.asList("1", "1", "1", "2", "2", "3"));
ArrayList<String> values = new ArrayList<>(Arrays.asList("2016-06-22 07:18:45", "2016-06-22 08:18:45", "2016-06-22 09:18:45",
"2016-06-22 03:18:45", "2016-06-22 04:18:45", "2016-06-22 01:18:45"));
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; keys.size() == values.size() && i < keys.size(); i++) {
String key = keys.get(i);
String value = values.get(i);
if (!map.containsKey(key) || dateAsNo(value) > dateAsNo(map.get(key))) {
map.put(key, value);
}
}
System.out.println(map);
}
public static long dateAsNo(String v) {
return Long.parseLong(v.replaceAll("\\D", ""));
}
It will only work if all the dates have the same format yyyy-MM-dd hh:mm:ss
You can use the following approach. Values will be overwritten only when date is newer (I am assuming you are not changing the date format)
Map<String,String> hashMap = new HashMap<>();
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
if(keys.size() != values.size())
return null;
for(int i=0; i<keys.size(); i++){
String keyVal = hashMap.get(keys.get(i));
if(keyVal==null || keyVal.compareTo(values.get(i))>0){
// second condition ensures value is only replaced if it is a later date
hashMap.put(keys.get(i), values.get(i));
}
}
return hashMap;
Try the same thing that you would do if you wre doing this manually. set your current key and go through your list till you find different key and put the current key and appropriate value (that is the value with the same index) in your map
public static void main (String [] args) throws IOException{
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1");keys.add("1"); keys.add("1");
keys.add("2");keys.add("2");
keys.add("3");
values.add("2016-06-22 07:18:45");values.add("2016-06-22 08:18:45");values.add("2016-06-22 09:18:45");
values.add("2016-06-22 03:18:45");values.add("2016-06-22 04:18:45");
values.add("2016-06-22 01:18:45");
Map<String,String> myMap = new HashMap<>();
String currentKey = keys.get(0); // set your current key and go through your list till you find the next key and put the current key and appropriate value (that is the value with the same index) in your map
for(int i = 0;i<keys.size();i++){
if(!currentKey.equalsIgnoreCase(keys.get(i))){
myMap.put(currentKey, values.get(i-1));
currentKey = keys.get(i);
}
if(i==keys.size()-1){
myMap.put(currentKey, values.get(i));
}
}
System.out.println(myMap);
}
you can write just like :
package java7.demo;
import java.util.*;
public class MapTest {
public static void main(String args[]){
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1");
keys.add("1");
keys.add("1");
keys.add("2");
keys.add("2");
keys.add("3");
values.add("2016-06-22 07:18:45");
values.add("2016-06-22 08:18:45");
values.add("2016-06-22 09:18:45");
values.add("2016-06-22 03:18:45");
values.add("2016-06-22 04:18:45");
values.add("2016-06-22 01:18:45");
LinkedHashMap<String,String>map = new LinkedHashMap<String,String>();
for(int i =0; i<keys.size();i++){
map.put(keys.get(i),values.get(i));
}
System.out.println(map);
}
}
as Map(include hashmap,linkedhashmap)replace old key value with new key value if old key value and new key value has same value,you will get 1->2016-06-22 09:18:45.at first it will put[ 1,2016-06-22 07:18:45]to map,in second loop,it will replace with [1,2016-06-22 08:18:45].int third time loop,it will replace with [1,09:18:45].to get data according to insertion Order,I use LinkedHashMap.

Adding entries to LinkedList inside ConcurrentHashMap not working

I have a ConcurrentHashMap that contains a string as a key and LinkedList as a value. The size of the list should not be more than 5. I am trying to add some elements to the list but when I print out the Map I see only the last added element. Here is my code:
private ConcurrentHashMap<String, LinkedList<Date>> userDisconnectLogs = new ConcurrentHashMap<String, LinkedList<Date>>();
public void addNewDateEntry(String userId, LinkedList<Date> timeStamps) {
if (timeStamps.size() >= 5) {
timeStamps.poll();
timeStamps.add(new Date());
userDisconnectLogs.put(userId, timeStamps);
} else {
timeStamps.add(new Date());
userDisconnectLogs.put(userId, timeStamps);
}
for (Entry<String, LinkedList<Date>> entry : userDisconnectLogs
.entrySet()) {
String key = entry.getKey().toString();
;
LinkedList<Date> value = entry.getValue();
System.out.println("key: " + key + " value: " + value.size());
}
}
Thank you!
Here for hashMap key must be unique. And from this code it seems key is always same so all the time it will overrite the data.

Hash of Hashes of Arrays in Java

I'm trying to implement Hash of Hashes of Arrays in Java and thought it would be nice if I will use anonymous blah blah(i forgot the exact term/I dont know how to call it).
HashMap<String, HashMap<String, String[]>> teams =
new HashMap<String, HashMap<String, String[]>>(){{
put("east", new HashMap<String, String[]>(){{
put("atlantic", new String[] { "bkn", "bos", "phi","tor", "ny" });
put("central", new String[] { "chi", "cle", "det", "ind", "mil" });
put("southeast", new String[] { "atl", "cha", "mia", "orl", "wsh" });
}});
put("west", new HashMap<String, String[]>(){{
put("northwest", new String[] { "den", "min", "okc", "por", "utah" });
put("pacific", new String[] { "gs", "lac", "lal", "phx", "sac" });
put("southwest", new String[] { "dal", "hou", "mem", "no", "sa" });
}});
}};
My question is if there is a another way to implement taking readability into consideration or completely perhaps completely change the implementation?
I know java is not the right tool but my boss told me to do so.
Also, please let me know of the right term. TIA
As long as we're not caring about run speed, why not use a language designed to express tiered data structures like JSON? JAVA has great external library support for it ...
Gson to the rescue!
#SuppressWarnings("unchecked")
HashMap teams =
new Gson().fromJson(
"{'east' : { 'atlantic' : ['bkn', 'bos', 'phi','tor', 'ny']," +
" 'central' : ['chi', 'cle', 'det', 'ind', 'mil']," +
" 'southeast' : ['atl', 'cha', 'mia', 'orl', 'wsh']}," +
" 'west' : { 'northwest' : ['den', 'min', 'okc', 'por', 'utah']," +
" 'pacific' : ['gs', 'lac', 'lal', 'phx', 'sac']," +
" 'southwest' : ['dal', 'hou', 'mem', 'no', 'sa']}}",
HashMap.class
);
http://code.google.com/p/google-gson/
Using a helper method
private void addTeams(String area, String codes) {
String[] areas = area.split("/");
Map<String, String[]> map = teams.get(areas[0]);
if (map == null) teams.put(areas[0], map = new HashMap<String, String[]>());
map.put(areas[1], codes.split(", ?"));
}
Map<String, Map<String, String[]>> teams = new HashMap<String, Map<String, String[]>>();{
addTeams("east/atlantic", "bkn, bos, phi, tor, ny");
addTeams("east/central", "chi, cle, det, ind, mil");
addTeams("east/southeast", "atl, cha, mia, orl, wsh");
addTeams("west/northwest", "den, min, okc, por, utah");
addTeams("west/pacific", "gs, lac, lal, phx, sac");
addTeams("west.southwest", "dal, hou, mem, no, sa");
}
You can replace
new String[] { "bkn", "bos", "phi","tor", "ny" }
with
"bkn,bos,phi,tor,ny".split(",");

Categories

Resources