Suppose I have, for example, an array of objects generated by parsing a document. These objects look like this:
Object{
id
text
anotherProperties
}
The first two attributes (id and text) are set during parsing, but now I want to add another Properties(additional attributes), which can't be set during parsing, because it is too complicated to determine them, but depends on text.
How can I achieve this in an elegant way?
In Java?
Thanks for responses
Perhaps use a HashMap with key of Integer (your id) and a value of DocProperites which consists of text and anotherProperites.
Then when you are ready to set anotherProperties you can retrieve the object from the HashMap and then set it.
For example
Map<Integer, DocProperties> map = new HashMap();
and DocProperties is
public class DocProperties {
private String text;
private String anotherProperties;
//plus the usual setters, getters and ctor
}
then when you want to set the anotherProperties you can call
map.get(key).setAnotherProperties(....);
If you wanted something more dynamic then you could use another HashMap instead of DocProperties. The HashMap could then have keys added and removed as you parse. I wouldnt advise this though as the code could become very messy and bug ridden.
Related
Is there a data structure in Java which can hold more than 4 values?
So something along the lines of
Map<String, String, String, String>;
This is needed to be able to reduce the number of if else statements I have. I would like to be able to do the following.
check if the data structure contains an element which matches a certain value, if it does then it assigns a link(which is string) to a variable and then adds a code and message to another variable which is related to that link.
if not is there a good workout around to achieve this?
Is there a data structure in Java which can hold more than 4 values?
There are lots of them.
The simplest is probably String[] which can hold 4 strings if you instantiate it like this:
new String[4]
And other Answers give other data structures that might meet your actual (i.e. unstated) requirements.
However, it is probably possible ... let alone sensible ... for us to enumerate all of the possible data structures that can meet your stated requirement.
Hint: you should try to explain how this data structure needs to work.
Hint 2: "the lines of Map<String, String, String, String>" does not help us understand your real requirement because we don't know what you mean by that.
UPDATE - Your explanation is still extremely vague, but I think you need something like this:
Map<String, MyRecord>;
public class MyRecord {
private String link;
private String code;
private String message;
// add constructor, getters, setters as required
}
There is nothing in the standard libraries, but Guava has a nice implementation; called
Multimap
If Guava is not an option in your environment, you will have to re-invent the wheel though.
Use can use MultiMap on Apache,
A MultiMap is a Map with slightly different semantics. Putting a value into the map will add the value to a Collection at that key. Getting a value will return a Collection, holding all the values put to that key
MultiMap mhm = new MultiValueMap();
mhm.put(key, "A");
mhm.put(key, "B");
mhm.put(key, "C");
Collection coll = (Collection) mhm.get(key);
Use Map of map:
Map<String, Map<String, Map<String, String>>>
Reading your question, It seams like you simply need a 'key-value' pair. Key being a 'String', which you have referred as 'a certain value' in your question. Value is a kind of wrapper object wrapping three Strings which you have referred as 'link, code and message'.
I suggest you can simply use
HashMap < String, Wrapper > map;
You can create a class ' Wrapper.java' which can contain three Strings, as instance fields
String link,code,message;
You can instantiate these fields in constructor and later can retrieve them using getter methods or also can have setters to set the values you need. You can provide a better contextual name to the class 'Wrapper.java'.
I have a bunch of strings with weird names (like this docFileeh934fhry) that contain text like this
System.out.println(docFileeh934fhry);
`.............document: 12345.....
...................
...............`
I want to rename these strings. So that the above string will be String doc12345
How can I do this?
I know how to get this number using Pattern.compile
Let's say I have this number String docNumber = "12345";
Now how can I dynamically create a new string?
I tried
String doc+docNumber = docFileeh934fhry; // no result
You might be able to do this with reflection, but it has to be said that this is a very poor approach.
Your naming of variables should not depend on any external input. Instead, give it a name that describes its contents and go from there.
What do you gain by naming it doc1?
If you are looping trough files all you probably want is a currentDocument. Any other variables (firstDocument, nextDocument, oldDocument, etc) you name according to their function, not their contents.
If you want a way to uniquely identify the correct document, create a class instead
class Document {
int id;
string contents;
}
After storing all these Document objects into a collection (like an ArrayList), you can just retrieve the document you need on basis of that id rather than having to mess around with a bunch of generated variables.
Another point to note: how would you even use this when you have 50 documents? 100? 10.000? This would be impossible to maintain.
If you don't want to create a custom class you can go with the HashMap<Integer, String> route.
This isn't how Java works. If you want to associate an object with a String, then use a Map such as a HashMap<String, String>.
Assign the string to the variable w/ the new name. Note that the new name will have to be have been defined when writing the code, it can't be computed on the fly (if that is what you are driving at).
You can't use + in a variable name. As above, you can't make variable names on the fly.
Here maybe one possible solution,use Hashmap,key is your varname(the way as you wish) and value is your string.
What approach shall I take if I would need to parse an incoming data with a dynamic set of fields. I can request a List of these fields though, so I know the amount of fields and their names at runtime. I don't know how to construct a model which I would use to parse the data and use afterwards. Thanks a lot for any suggestions.
I'd go with the attribute name/ attribute value pair within a javabean, but, in order to keep track, I'd also add some business class (or interface) enumerating the allowed value for attributes.
Let the code speak:
class MyBean {
String name;
Object value;
// Getters and setters
}
Now, if one of those list rappresents a dog, we may have a class like:
class Dog {
private List<MyBean> dataSet;
// Enumerate the possible values of MyBean.name for a valid Dog object
public final static String KIND = "kind";
public final static String AGE = "age";
public final static String BARFES = "heBarf";
// Use a convenience Set for checks
public static Set<String> validAttributes;
// Put valid values in the convenience set once for all
static {
// trivial code to initialize the validAttributes set
}
// We won't add setters, better constructing a new object every time
public Dog(List<MyBean> v) {
dataSet = v; // better copying ? as usual it depends on scenarios.
}
// A convenience static to parse a string into this object.
public static Dog parse(String theStream) {
// cannot write since I don't know how is format, but this method can use the enumerations of the attribute names for checking.
}
// Accessor
public int getAge() {
return dataSet.get(Dog.AGE);
}
}
Well possibilities are infinite. You can have a base class (a List) and use it as a base class for business classes (adding just getters and proper constructor) or use a List as a private data member (remember to keep it hidden - don't give a direct access to its reference).
You can probably go with some enum too. The important thing, in using this kind of meta-datas (because in the end these are metadatas) is keeping track of valid names (there's no compile checks, so you need to have some sort of quick and dirt way to monitor things).
PS: Don't mind code, is actually just a proof of concept (probably won't even compile).
Though your question is is not clear, I will try to answer. If you know the field names then you will have to do as it is done on command line, supply parameter and retrieve their value.
If you know the delimiter, then parsing is easy. For complex data structure you can construct the syntax with regular expression to parse.
You can use reflection.
Another easy way:
1) parse the dynamic List as a JSON string in a for loop, OR make a map instead of list with the key as field name and value as field value.
2) convert the JSON string or map with any JSON lib.
I need to store few data pairs in array. Maybe few dozens. I only need to append, no need to delete, no need to search. Then I will access by index. Each pair is String value and Integer value. Java provides so many way to do this, which is the common practice for something like that? Two arrays? A class in an array?
I know how to do this in JavaScript:
var data = []
data.push(['Some name', 100])
//somewhere else
data.push(['Other name', 200])
but I need a solution for Java
Thank you.
For example you can create Pair class (or use implementations from apache commons) to store two elements in List.
List<Pair<String, Integer>> l = new ArrayList<>();
l.add(new Pair<String, Integer>("Some name", 100));
See Generic pair class and Java Pair<T,N> class implementation to see how you can implement Pair class.
It really depends, but in general I think it is better to create an object and use a list of it:
public class MyObject {
private String myString;
private Integer myInt;
// getters setters
}
And use:
List<MyObject> = new ArrayList<>();
(you can also use Pair instead)
If the strings (or ints) are unique, you can use Map, but it is harder to get the insert index.
Another option is just two lists, one for Strings, one for Integers, and use same index in both lists.
I go by using POJO as suggested above for this as this helps to define getter and setter for all the attributes of POJO, compare the objects by overriding equals and hashCode methods. By using getter and setter you know what is stored in what field and comparison can provide you sorting of objects as per your requirements. So this approach is cleaner and extensible for accommodating new requirements too. Also as you are putting data with sequential key so each instance of Pojo can be put in List (if required in sorted order.
Hi i have to validate the database values with the UI displayed values so I am using Watij as an automation tool.
The problem arises when i have to store the database values into the hashmap.
Suppose the database is having 3 fields Name, Email and Address.
And after firing the query the fetched rows are 10.
I am taking the field values as the Key in hashmap and the retrieved rows as the values.
I am unable to store the values in hashmap. When i used the hashmap the values got overridden and at last i always got the single values for the respective keys. I tried declaring the hashmap having two parameters as string and an string[] but i was unable to read the final values.
Can anybody help as i am not a java expert.
Thanks.
Where have you declared the string? You will have to declare it inside the loop(where you loop through your resultset). If you are not creating a new object inside the loop, the reference of the same string would be stored in all the values of the hashmap and you would get a single value in your hashmap. If the code was also mentioned here, it would be easy to pinpoint the exact problem.
when storing object in hashmap, you can use the hashcode of that object as key and then can save the object itself as the value, but make sure that you implement hasCode() and equals method properly, as u know, hashmap internally used hashcode() and 'equals` method for storing data.
Now when implementing hashcode or equals method, you can use any attribute (column of that row), which u think, that uniquely identify that row.
And moreover, performance wise this will be a better approach.
You can make a map like as HashMap<String, Data> where the first argument is the key (I suppose a String, you can use what you want) and Data is a a class that contains the data values for the key. Data may be:
public class Data {
private String name;
private String address;
private String email;
...
}
You can add object to the map with map.put(key, new Data(...)).
A more simple way is use array, in a map like HashMap<String,String[]>, but is not very useful. The Java idea with DB query is to create object to encapsulate every record.
Well in a map, the keys need to be unique, so if you keep add (email,blabla#hotmail.com) and it already had (email,nana#gmail.com) they you would just override the first one. If what you want is just a list of emails, adresses and names wouldn't it be better to make a class called person or something and add those to a list?
Like person(name,email,adress) then add that to a list.