It seems that java.util.Properties assumes one value per propery key. That is,
foo=1
foo=2
is not expected,
Is there a class for this kind of multi-value property sheet, which also provides the load method?
Try:
foo=1,2
String[] foos = properties.getProperty("foo").split(",");
The java.util.Properties function is pretty limited. If you want support list, you might want try PropertyConfiguration from Apache Commons Configuration,
http://commons.apache.org/configuration/userguide/howto_properties.html#Using_PropertiesConfiguration
With it, you can set any delimiters to your list and it will split for you automatically. You can also do other fancy things in properties file. For example,
foo=item1, item2
bar=${foo}, item3
number=123
You can retrieve it like this,
Configuration config = new PropertiesConfiguration("your.properties");
String[] items = config.getStringArray("bar"); // return {"item1", "item2", "item3"}
int number = config.getInt("number", 456); // 456 is default value
Correct answer by Nick.
Or, if you can give a different subname to each value, you could have your properties be:
my.properties
foo.title=Foo
foo.description=This a big fat foo.
This won't provide the load method but a place to store them you could use a apache commons multivaluemap:
"A MultiValueMap decorates another map, allowing it to have more than one value for a key. "
This is often a requirement for http request parameters...
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/MultiValueMap.html
If you have a more complex example you might use the following:
# pairs of properties
source1=foo
target1=bar
source2=anotherFoo
target2=regardingBar
source3= ...
In your code you will have to search:
Map<String, String> myMap = new HashMap<>();
for (int i=1; i<max; i++) {
String source = properties.get("source" + i);
String target = properties.get("target" + i);
if (source == null || target == null) {
break;
}
myMap.put(source, target);
}
Drawback: updating the properties file. If you remove values *2, all the following values will not be added. To improve you might want to replace the break with a continue and stick to a maximum of allowed pairs.
Related
Hopefully someone is able to help, I'm relatively new at java and trying to work out how to use the properties function to read multiple property values, not necessarily in order or the full list and then put them into either an array or a string so that I can then pass to another class to do "stuff" like write to a file. There could potentially be hundreds of property values and only wanted to pick the ones I wanted.
I'm able to get one like properties.getProperty("ip"); and assign to a string but having issues with multiple as per below...
Any help would be greatly appreciated.
Properties properties = new Properties();
try {
properties.load(new FileInputStream(args[0]));
}
catch (IOException e) {
System.out.println("Error - IOException - File not found...");
}
String model = properties.getProperty("model");
String codeLevel = properties.getProperty("codeLvl");
String[] dmdCommand = new String[properties.getProperty("ip")
+ properties.getProperty("rangeS")
+ properties.getProperty("rangeL")
+ properties.getProperty("PhyPG")
+ properties.getProperty("PhyLDEV")
+ properties.getProperty("PhyProc")
+ properties.getProperty("PhyExG")
+ properties.getProperty("PhyExLDEV")
+ properties.getProperty("PhyCMPK")];
If you need additional info or data samples happy to supply.
Cheers and thanks in advance :)
If you know the "keys" to the properties, you can use an ArrayList of strings to store the properties.
for example:
List<String> propertyList = new ArrayList<String>();
propertyList.add(properties.getProperty("rangeS"));
Here I'm assuming that you do not know how many keys are you going to pick up from the properties and hence the suggestion to use an ArrayList, but if you do know the number of keys to be picked, you should definitely use an array of strings.
for example:
String[] propertyArray = new String[limit];
for(int i=0;i<limit;i++){
propertyArray[i]= new String(properties.getProperty(myKey));
}
here, "myKey" can be coded to change dynamically.
I need to save two depending Strings (action and parameter) into a file or a hashtable/map or an Array, depending what is the best solution for speed and memory.
My Application iterates through a large amount of forms on a website and i want to skip if the combination (String action,String parameter) already was tested and therefore saved. I thing an Array would be too slow if I have more then thousands of different action and parameter tupels. I´m not experienced enough to chose the right method for this. I tried a hashtable but it does not work:
Hashtable<String, String> ht = new Hashtable<String, String>();
if (ht.containsKey(action) && ht.get(action).contains(parameter)) {
System.out.println("Tupel already exists");
continue;
}
else
ht.put(action, parameter);
If a action and parameter will always be a 1-to-1 mapping (an action will only ever have one parameter), then your basic premise should be fine (though I'd recommend HashMap over Hashtable as it's faster and supports null keys)
If you will have many parameters for a given action, then you want Map<String, Set<String>> - where action is the key and each action is then associated with a set of parameters.
Declare it like this:
Map<String, Set<String>> map = new HashMap<>();
Use it like this:
Set<String> parameterSet = map.get(action); // lookup the parameterSet
if ((parameterSet != null) && (parameterSet.contains(parameter)) { // if it exists and contains the key
System.out.println("Tupel already exists");
} else { // pair doesn't exist
if (parameterSet == null) { // create parameterSet if needed
parameterSet = new HashSet<String>();
map.put(action, parameterSet);
}
parameterSet.add(parameter); // and add your parameter
}
As for the rest of your code and other things that may not be working:
I'm not sure what your use of continue is for in your original code; it's hard to tell without the rest of the method.
I'm assuming the creation of your hashtable is separated from the usage - if you're recreating it each time, then you'll definitely have problems.
A method of mine returns a Map<A,B>. In some clearly identified cases, the map only contains one key-value pair, effectively only being a wrapper for the two objects.
Is there an efficient / elegant / clear way to access both the key and the value? It seems overkill to iterate over the one-element entry set. I'm looking for somehing that would lower the brain power required for people who will maintain this, along the lines of:
(...)
// Only one result.
else {
A leKey = map.getKey(whicheverYouWantThereIsOnlyOne); // Is there something like this?
B leValue = map.get(leKey); // This actually exists. Any Daft Punk reference was non-intentional.
}
Edit: I ended up going with #akoskm solution's below. In the end, the only satisfying way of doing this without iteration was with a TreeMap, and the overhead made that unreasonable.
It turns out there is not always a silver bullet, especially as this would be a very small rabbit to kill with it.
If you need both key/value then try something like this:
Entry<Long, AccessPermission> onlyEntry = map.entrySet().iterator().next();
onlyEntry.getKey();
onlyEntry.getValue();
You can use TreeMap or ConcurrentSkipListMap.
TreeMap<String, String> myMap = new TreeMap<String, String>();
String firstKey = myMap.firstEntry().getKey();
String firstValue = myMap.firstEntry().getValue();
Another way to use this:
String firstKey = myMap.firstKey();
String firstValue = myMap.get(myMap.firstKey());
This can work as an alternate solution.
There is a method called keySet() to get set of keys. read this thread.
else {
A leKey=map.keySet().iterator().next();
B leValue; = map.get(leKey); // This actually exists. Any Daft Punk reference was non-intentional.
}
Using for-each loop and var :
for(var entry : map.entrySet()){
A key = entry.getKey();
B value = entry.getValue();
}
I have a HashSet of Strings in the format: something_something_name="value"
Set<String> name= new HashSet<String>();
Farther down in my code I want to check if a String "name" is included in the HashSet. In this little example, if I'm checking to see if "name" is a substring of any of the values in the HashSet, I'd like it to return true.
I know that .contains() won't work since that works using .equals(). Any suggestions on the best way to handle this would be great.
With your existing data structure, the only way is to iterate over all entries checking each one in turn.
If that's not good enough, you'll need a different data structure.
You can build a map (name -> strings) as follows:
Map<String, List<String>> name_2_keys = new HashMap<>();
for (String name : names) {
String[] parts = key.split("_");
List<String> keys = name_2_keys.get(parts[2]);
if (keys == null) {
keys = new ArrayList<>();
}
keys.add(name);
name_2_keys.put(parts[2], keys);
}
Then retrieve all the strings containing the name name:
List<String> keys = name_2_keys.get(name)
You can keep another map where name is the key and something_something_name is the value.
Thus, you would be able to move from name -> something_something_name -> value. If you want a single interface, you can write a wrapper class around these two maps, exposing the functionality you want.
I posted a MapFilter class here a while ago.
You could use it like:
MapFilter<String> something = new MapFilter<String>(yourMap, "something_");
MapFilter<String> something_something = new MapFilter<String>(something, "something_");
You will need to make your container into a Map first.
This would only be worthwhile doing if you look for the substrings many times.
I am having an option in my website for the user i.e: "Settings" in that I given 3 options(TextBoxes) to enter details: 1.E-mail, 2.SMS, 3.MMS.. in this user can enter another mail id: its an optional thing but, if he enter the both or same which is neccesary e-mail and optional or same then, I have to tell that "given e-mail" alredy exist.
I am sending this data as ArrayList that to coverted as JSON object.
What is the best way to find the duplicate and notify that to user
Help me in this
Thanks in advance
Either parse it into Java collections with a JSON framework of your choice, then check for duplicates or use JavaScript to directly work on the JSON.
If you have the ArrayList anyway, why don't iterate over that?
Please do the following
HashSet hashSet = new HashSet(arrayList1);
ArrayList arrayList2 = new ArrayList(hashSet) ;
if(arrayList2.size()<arrayList1.size()){
//duplicates exits
}
You can do what Ammu posted, but this will not identify the duplicate entry. If you have the ArrayList as a Java object (if not, convert it into one), convert the ArrayList into a HashSet, compare the size to identify if there are duplicate entries. If so, you need to sort the ArrayList in order to find the duplicate entry.
Collections.sort(arrayList);
for(int i = 1; i < arrayList.size() - 1; i++){
if (arrayList.get(i).equals(arrayList.get(i - 1))){
// found duplicate
System.out.println("Duplicate!");
}
}
this works only if the entries of the ArrayList implement the sortable interface. But since your ArrayList is filled with strings this is the case.
Based on what you described
"... in this user can enter another
mail id: its an optional thing but, if
he enter the both or same which is
neccesary e-mail and optional or same
then, I have to tell that "given
e-mail" alredy exist."
I would alert the user using Javascript and avoid the HTTP Request/Response round-trip to the server:
...
// before submitting the form
if (document.getElementById('requiredEmail').value == document.getElementById('optionalEmail').value) {
alert("The optional email must be different than the required email");
}
...
As suggested before by other user, you can just create a Set based on the ArrayList if you are validating the input in the backend...
String[] parsedInput = new String[] { "SMS-Value", "MMS-Value", "email#domain.com", "email#domain.com" }
List<String> receivedList = Arrays.asList(parsedInput);
Set<String> validatedList = new HashSet<String>(receivedList);
if (validatedList.size() < receivedList.size()) {
throw new IllegalArgumentException("The email addresses provided are incorrect.");
}
If you want to find the duplicates then you can iterate over the list and find.
like:
Map<Object, Integer> map = new HashMap<Object, Integer>();
for(Object obj : list)
{
if(map.containsKey(obj))
{
map.put(obj, map.get(obj)+1);
}
else
{
map.put(obj, 1);
}
}
Objects in the map having value more than 1 are duplicate.
If you just want to get rid of duplicates (rather than knowing which are actually duplicates)
Ex:
Set set = new HashSet(list);
set can not have duplicate elements, so it will remove all duplicates.