I am trying to figure out how to create Typescript interface for HashMap<String, Pojo> I have tried the below variations but:
export interface ServerResponse {
// forWhomAdd: Array<ForWhomAdd>; // size/length is undefined
// forWhomAdd: Map<string, Address>; // size/length is undefined
forWhomAdd: { [firstLastName: string]: Address }; // How do I access keys and values?
}
I'd prefer not to do this the third way because I'm loosing my types which I'm trying to define.
This is how it looks when I log it:
{testKey: {property: value, prop: value}}
So I can get the Object by:
let serRes: ServerResponse = data;
serRes.testKey // gives back the object
But I don't know keys and I need to loop over serRes.
Assuming your data has list of ServerResponse.
let serRes: Array<ServerResponse> = data;
But I don't know keys and I need to loop over serRes.
you can get the values of the Object with keys() method of Objectclass.
Object.keys(this.serRes).map(key => this.serRes[key])
UPDATE :
I have created stackblitz for your case check it here.
I have list of words which I need to load to ArrayList< String >
prefix.properties
vocab\: = http://myweb.in/myvocab#
hydra\: = http://www.w3.org/ns/hydra/core#
schema\: = http://schema.org/
"vocab:" is actually "vocab:" .Slash(\) is used to read colon(:) character because it is special character.
Dictionary.java
public class Dictionary {
public static ArrayList<String> prefix = new ArrayList<>();
static {
Properties properties = new Properties();
InputStream input = null;
input = ClassLoader.getSystemResourceAsStream("prefix.properties");
System.out.println(input!=null);
try {
properties.load(input);
} catch (IOException e) {
e.printStackTrace();
}
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
for(Map.Entry<Object, Object> E : entries)
{
prefix.add(E.getKey().toString());
prefix.add(E.getValue().toString());
}
}
}
In Dictionary.java , ArrayList prefix will have
prefix = [
"vocab:",
"http://myweb.in/myvocab#",
"hydra:",
"http://www.w3.org/ns/hydra/core#",
"schema:",
"http://schema.org/"
]
I am querying some data in another class.
For eg:
public class QueryClass
{
public ArrayList<String> queryResult(String findKey)
{
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> prefix = Dictionary.prefix;
Iterator<String> iterator = prefix.iterator();
while (iterator.hasNext())
{
String currentKey = iterator.next()+findKey;
/**
Here my logic to search data with this currentKey
*/
}
return result;
}
}
Problem :
I want to avoid this method to load from .properties file because there is possibility of odd number of elements can be present while .properties file provide (key,value) pair way to store data.
Reason why I have to load from separate file ? Because In future I will have to add more keywords/String thats why I put it in prefix.properties file.
Is there any alternative way to do this?
Do not re-invent the wheel.
If you can define the file format, then just go for java properties.
You see, the Properties class has a method getProperty(String, String) where the second argument can be used to pass a default value for example. That method could be used in order to fetch keys that don't come with values.
I would be really careful about inventing your own format; instead I would look into ways of re-using what is already there. Writing code is similar to building roads: people forget that each new road that is built translates to maintenance efforts in the future.
Besides: you add string values to a list of strings by calling list.add(strValue). That is all that is to that.
Edit on your comment: when "java properties" are not what you are looking for; then consider using other formats. For example you could be persisting your data in some JSON based format. And then just go for some existing JSON parser. Actually, your data almost looks like JSON already.
I'm not sure why you need to use ArrayList but if you want to pass these property keys/values, there are 2 better ways:
Use Properties itself.
Convert to HashMap.
I have a properties (cant change this file) and it looks like:
aaa.bbb.ccc.first=my first value
aaa.bbb.ccc.second=my second value
aaa.bbb.ccc.third=my third value
If I need any value in java classes I use i18n.getText("aaa.bbb.ccc.first") but it works only for single value.
Problem is because I dont know:
-value's names
-how many values are in aaa.bbb.ccc.~
How is it possible to get list of value aaa.bbb.ccc~?
You could use a MapFilter. Use the MapFilter(Properties p, String prefix) constructor.
public void test() {
Properties props = new Properties();
props.put("aaa.bbb.ccc.first", "my first value");
props.put("aaa.bbb.ccc.second", "my second value");
props.put("aaa.bbb.ccc.third", "my third value");
props.put("Other.props", "others");
MapFilter<String> filtered = new MapFilter(props, "aaa.bbb.ccc.");
for (Map.Entry<String, String> e : filtered.entrySet()) {
System.out.println("Key: " + e.getKey() + " Value: " + e.getValue());
}
System.out.println(filtered);
}
Hash maps are not meant for the kind of lookup you want to do: Tries and radix trees are. There is an implementation of the Patricia trie data structure (i.e., binary radix trees) in Apache Commons Collections: Just create a trie from your Map<String, Whatever> (you have a nice constructor at the purpose) and with prefixMap("aaa.bbb.ccc") you obtain the submap of all the entries whose key have that prefix.
Properties has a method propertyNames(). You can use that to get all the keys then do whatever you want from there.
I have come across this question on StackOverflow which asks about converting JSON to Java. The answer shows that another class is modelled to represent the JSON data as well as an object being created and I don't understand why.
Does that object now contain all the information after Gson reads the content or only one key/value pair? If it only contains 1 key/value pair, I'm assuming I would need to create multiple objects for the JSON that I have below which I can the use a loop to iterate over and add the values to a drop down menu?
{
"1": "Annie",
"2": "Olaf",
"3": "Galio",
"4": "TwistedFate",
"5": "XinZhao",
"6": "Urgot",
"7": "Leblanc",
"8": "Vladimir",
"9": "FiddleSticks",
"10": "Kayle",
"11": "MasterYi",
"12": "Alistar",
"13": "Ryze",
"14": "Sion",
"15": "Sivir",
"16": "Soraka",
"17": "Teemo",
"18": "Tristana",
"19": "Warwick",
"20": "Nunu"
}
Essentially what I am aiming to do is:
1) Create a list of names with the Values.
2) Sort the list of names (as it comes unsorted) in alphabetical order
3) Loop through the list and add each name to a drop down menu
4) When a name in the drop down menu is selected, the key associated with that value is passed to another url which receives more data.
Sorry if this is unclear. I've spent a couple of hours trying to understand how to get elements from JSON and display it, as well as trying to create a list where I can use the key to display information the name but have had no luck except for using a for-each loop.
Let's use Jackson's feature that allows you to map any property to a single method (you don't really need a getter here I believe). Just swap the key and value in this universal setter, and add to a TreeMap, which is already sorted by key (name). Then you can output the keys (names) in the alphabetical order and get an ID by name easily.
public static void main(String[] args) throws IOException {
String json = "....."; // your JSON string here
com.fasterxml.jackson.databind.ObjectMapper mapper =
new com.fasterxml.jackson.databind.ObjectMapper();
ReverseMap pairs = mapper.readValue(json, ReverseMap.class);
for (Map.Entry<Object, String> entry : pairs.getValues().entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
public class ReverseMap {
private TreeMap<Object, String> mapping = new TreeMap<>();
#com.fasterxml.jackson.annotation.JsonAnySetter
public void add(String name, Object value) {
mapping.put(value, name);
}
public Map<Object, String> getValues() {
return mapping;
}
}
Gson Bean Mapping Solution
Okay, what you have is a bit unusual for a JSON object; the keys (the numbers in your case) essentially represent properties of their contained object. That's workable, but you have to understand that, for example, when looking for "Annie" in the JSON object, if you use Gson to map to a "bean" class, which we'll call Data (as in the linked example), then you'd have to create a data object like so:
class Data {
private String _1;
// ...
private String _20;
public String get1() { return _1; }
public void set1(String _1) { this._1 = _1; }
// ...
public String get20() { return _20; }
public void set20(String _20) { this._20 = _20; }
}
And by using Data data = new Gson().fromJson(myJsonString, Data.class); on the given string, you'd be able to find "Annie" by calling... uh... data.get1()?
Clearly, this isn't a good solution.
Better Solutions
Since your data doesn't follow the typical format for a JSON object, you have two options:
If you can, refactor your JSON representation to a more verbose, but better representation for parsing.
Use a different approach to parse the existing JSON.
Solution 1: Changing the JSON representation
Refactoring the JSON would result in an object that (preferably) would look like this:
{
"champions" : [
{
"index" : 1,
"name" : "Annie"
},
{
"index" : 2,
"name" : "Olaf"
},
// ...
]
}
This could map easily to a couple of beans that look like this:
class Data {
private List<Champion> champions;
// TODO getters and setters
}
class Champion {
private int index;
private String name;
// TODO getters and setters
}
However, this adds a lot of unnecessary clutter to the JSON object, and isn't really necessary with only two fields per champion (the name, and their index).
You could simplify that further like so:
{
"champions" : [
"Annie",
"Olaf",
// ...
]
}
The bean class for that would then be:
class Data {
private List<String> champions;
// TODO getters and setters
}
Much simpler, but still requires a change to the JSON you're getting, which in some situations isn't possible. If you used this, though, you could also get rid of the "bean" class entirely, via:
List<String> champions = (List<String>) new Gson().fromJson(myJsonString, new TypeToken<List<String>>(){}.getType());
Solution 2: Changing how the JSON is parsed
The arguably better and cleaner solution is just to change how the JSON is parsed.
The goal here (if I understand you correctly) is to parse the JSON and spit out a collection of strings representing each champion's name, accessible by the numeric index of the champion in the JSON representation.
As such, and because of the way the JSON object is laid out as a simple mapping of strings to strings, we can use Gson to pipe directly into a Map<String, Object>, like so:
Map<String, String> mappedValues = new Gson().fromJson(myJsonString, Map.class);
String anniesName = mappedValues.get("1"); // "Annie"
String olafsName = mappedValues.get("2"); // "Olaf"
boolean hasTwentyOneElements = mappedValues.containsKey("21"); // false
This is shorter, requires no "bean" classes, and keeps the original JSON representation. The downside is that you can't easily tell whether the indices of each entry are correct and consistent; ie. if someone types in the wrong number, or deletes one of the entries.
To get a container of all keys, you just use mappedValues.keySet(), and to get a container of all key-value pairs, you use mappedValues.entrySet(), which gives you a Set<Map.Entry<String, String>>. Both of those can be iterated over, and may be in random order (I'm not sure whether the underlying Map implementation preserves insertion order or not).
To get the index for a given name (ie. champ), you'd use something similar to the following:
String index = null;
for (Map.Entry<String, String> entry : mappedValues.entrySet()) {
if (champ.equals(entry.getValue())) {
index = entry.getKey();
break;
}
}
Of course, you'd have to check to see if index is null after this, and handle that appropriately, but it's easily doable.
EDIT: #vempo's answer provides a cleaner, more efficient lookup strategy by means of inverting the map (although the answer is written for Jackson, instead of Gson); an adaptation of this for Gson is as follows (and yes, there is a vastly superior version in java-8, left out for sake of availability):
public Map<String, String> invertMap(Map<String, String> input) {
Map<String, String> newMap = new LinkedTreeMap<String, String>(); // TODO Pick optimal storage class
for (Map.Entry<String, String> entry : input.entrySet()) {
newMap.put(entry.getValue(), entry.getKey());
}
return newMap;
}
// ...
Map<String, String> mappedValues = invertMap(new Gson().fromJson(myJsonString, Map.class));
String annieIndex = mappedValues.get("Annie"); // "1"
String olafIndex = mappedValues.get("Olaf"); // "2"
It's worth noting that this sacrifices efficiency of constructing the map by effectively building it twice (once by Gson and once more to invert), but it makes value lookup much more efficient.
I am using file properties file and loop through that file.
Properties Config= new Properties();
Config.load(new FileInputStream("c:\\Config.properties"));
Enumeration e = Config.propertyNames();
while (e.hasMoreElements())
{ String key = (String) e.nextElement();
System.out.println(key + " -- " + Config.getProperty(key));
}
My Input in C:\Config.properties is
Input
fun1= abc
fun2=pqr
fun3 mno
Output
fun2 -- pqr
fun1 -- abc
fun3 -- mno
How can i get this what exactly in the Config file.
That's not possible using java.util.Properties as it extends java.util.Hashtable which is by nature unordered.
Your best bet is reading and parsing it yourself using for example a BufferedReader or a Scanner.
I however wonder why ordering is that important. There may be alternatives which I can only suggest if you elaborate the functional requirement behind this all in detail. Based on the given example, the closest what I can suggest you is the following:
List<String> funs = new ArrayList<String>();
for (int i = 1; i < Integer.MAX_VALUE; i++) {
String fun = config.getProperty("fun" + i);
if (fun == null) break;
funs.add(fun);
}
// ...
Properties is not an ordered map so you might want to create a SortedMap from the loaded properties. This guarantees that the keys are naturally ordered. But i assume you want the order to be the one that you specify in the properties file. There is no way to do it automatically. You need to code it yourself.
As BalusC suggested read line by line from beginning using file API, create a Pair/Tuple object and insert it in the List object or add it to SortedMap based upon your usage requirement
I would be shocked if there isn't a library that already does this. Try Apache Configuration, for example.