I have some objects with Date parameters. What collection will be best for storing them and later querying for object/objects with particular date ? (like given as a String or java.util.Date format) ?
EDIT:
I was trying to use TofuBear's solution, but cannot make it work. let's say I am calling my function (which returns Map) with a list of objects, and Date object. What next ? I was trying different methods but everything is just bloody red from NetBeans's errors:
public Map<Date, List<Person>> createDateList(Date date, List<Person> list){
Map<Date, List<Person>> map = null;
}
This however does not solve problem of querying, cuz I'm just creating a map with one object. I need to have a list of all objects (which have Date field) and their dates in a map. Am I thinking correctly ?
Probably a Map<Date, WhateverTypeYouWant> or Map<Date, List<WhateverTypeYouWant>> if there are multpile values with the same date.
Then you would add them something like this:
map.put(object.getDate(), object);
Edit based on the comment:
For the List version I use something like this (untested from memory... but pretty sure it is right):
List<WhateverTypeYouWant> list;
list = map.get(object.getDate())
if(list == null)
{
list = new ArrayList<WhateverTypeYouWant>();
map.put(object.getDate(), list);
}
list.add(object);
Sounds like a Map<Date, YourObject> (or Map<String, YourObject> if you prefer so) would do the job.
Maps come in different flavours, the most generally used is HashMap.
Map<Date, Other>, as others have said, but if you are interested in more than getting an entry that matches a given date exactly then you would want to look into using a NavigableMap. A navigable map will allow you to get entries that are close to what you are searching for if nothing matches exactly.
If you use Map<Date, SomeObject> like other have suggested, you will only be able to do exact searches and in case you change Date inside SomeObject you'll need to manually update the Map. Even more work if you choose to use Map<Date, List<SomeObject>>.
Instead use List<SomeObject> and use Collections.binarySearch(). This requires Collection to be sorted and you need to write custom java.util.Comparator.
private class SomeObjectComparator implements Comparator<SomeObject> {
#Override
public int compare(SomeObject o1, SomeObject o2) {
// this breaks equality rule for Set
// do not use in Sets
return o1.date.compareTo(o2.date);
}
}
then use it like this (preferably wrap it in helper method):
List<SomeObject> someList = new ArrayList<SomeObject>
Comparator comparator = new SomeObjectComparator();
Collections.sort(someList, comparator);
int resultIndex = Collections.binarySearch(someList, someSearchedObject, comparator)
Given this comparator, binarySearch() will only search by Date not by other properties of SomeObject.
Also look for meaning of resultIndex in Collections.binarySearch()
In side the collection API stored the reference addresses of the attribute (of like list, linked List ) for which required the boxing on primitive data type element, in its correspondence Wrapper class type object and that one object are automatically up-castes to Object type class (Object class is the Super class of every Class) And this reference object can pass for any other program (Inside same or different Package) with the Multiple Resection on the OWN date (Like only reading, removing, Updating, Reading only one time, adding more element inside list) according with requirement. for which reference object is only usefull to avoid multiple problems.
Related
I have an ArrayList of Objects. The object has five fields: id, date, name, value, adjusted_value. The list may hold multiple entries with the same name, and I am having trouble devising an efficient way to condense the list based on the name to where I will a list of similar objects but the values stored will be name, sum(value), sum(adjusted_value).
Is there an efficient way to do this? My current method has for loops inside of a do-while.
Clarfication:
I have a list of obejcts :
{id,date,name,value,ajusted_value},
{1,"10/30/2014","peaches",4,3}
{2,"10/30/2014","apples",2,2}
{3,"10/31/2014","peaches",3,1}
.
.
.
I want to condense to list based the name value to one that looks like this:
{null,null,"peaches",7,4}
{null,null,"apples",2,2}
.
.
.
However, I found that HashMap's put() functionality will perform what I desire automatically, but now I need to do this sort of action in Javascript if possible.
You can define a Map where the key is the name and value is the object instance.
Go through the list and for each instance check whether it exists in the map.
If not just add to the map. map.put(instance.name,instance)
If it's already added to the map just
mapInstance=map.get(instance.name);
mapInstance.value+=instance.value;
mapInstance.adjusted_value+=instance.adjusted_value;
After the loop you have the filled map with grouped data
I would use Guava in two step. Use a NameFunction to convert the list to a Multimap. Use a CondenseFunction to convert the values of the Multimap.
Function<MyClass, String> toName = new Function(){
public String apply(MyClass input){return input.name;}};
ImmutableListMultimap<String, MyClass> multimap = Multimaps.index(myList, toName);
Map<String, Collection<MyClass>> map = multimap.asMap();
Function<Collection<MyClass>, MyClass> condense= new Function(){
public MyClass apply(Collection<MyClass>input){
// create sums here
}};
Map<String, MyClass> condensed = Maps.transformValues(map, condense);
Collection<MyClass> result = condensed.getValues();
Multimaps.index()
Maps.transformValues
I have a simple caching system in Java that maps an object id (Integer) with a timestamp (Long) and the latter to a List<Object>. I map this situation with two maps:
Map<Integer, Long> objectTimestamps = ...
Map<Long, List<Object>> timestampToList = .... //I know, Here I can use something like a Guava's MultiMap, but it is not really important at this point
I studied a lot of the collections from libraries like Guava, but I didn't found any specific data structure to be used in this case. Can you propose another way to hold this data? Please, consider that I read/insert this values continuously in my algorithm.
PS: In my example I map the timestamp to a list of Object instances, but sometimes I map the timestamp to just a simple Object.
I would simply do:
public class TimestampObjects {
private long timestamp;
private List<Object> objects;
// + constructors, getters, setters
}
And the map would become: Map<Integer, TimestampObjects>
You can use Apache Pair.
The map will be: Map<Integer, Pair<Long, List<Object>>.
To add something in the map, you simply do the following:
map.put(integerValue, Pair.of(longValue, objectList));
If I have a HashMap hashM, an ArrayList arrayL. If I would like to use an if statement to check whether hashM has all the elements in arrayL, how can I do that?
I cm currently using something like
if (hashM.values().containsAll(arrayL.getPreReqs()))
However it doesn't work properly.
Dear all thanks for the answers!
Actually containsAll works however the way I structure the my codes is wrong so that I got wrong outcomes. Now it has been fixed.
Cheers!
Given
Map<?,?> map = new HashMap<?,?>();
List<?> list = new ArrayList<?>();
The approach you tried (well, nearly, as pointed out by Marko Topolnik) is indeed correct:
if (map.values().containsAll(list)) { ... }
(Or map.keySet().containsAll(list) if you were interested in the map keys instead of values.)
For this to work as expected for custom types, you of course must have implemented equals() and hashcode() correctly for them. (See e.g. this question or better yet, read Item 9 in Effective Java.)
By the way, when working with Java Collections, it is good practice to define fields and variables using the interfaces (such as List, Set, Map), not implementation types (e.g. ArrayList, HashSet, HashMap). For example:
List<String> list = new ArrayList<String>();
Map<Integer, String> map = new HashMap<Integer, String>();
Similarly, a more "correct" or fluent title for your question would have been "How to check whether a Map has all the elements of a List?". Check out the Java Collections tutorial for more info.
Your code is correct except..
if (hashM.values().containsAll(arrayL)) {....}
[EDIT]
You can use HashMap.containsValue(Object value)
public boolean containsList(HashMap<K, V> map, List<V> list) {
for(V value : list) {
if(!map.containsValue(value)) {
return false;
}
}
return true;
}
Your code should work - but will not be particularly efficient. You need to compare every element in the list with every element in the map.
If (and only if) you can easily extract the key of the map from the elements then you would be better off looping through your List and for each element do map.containsKey(getKey(elem)), this will be much faster.
If you are doing this sort of comparison a lot and you cannot map from element to key then it may be worth keeping a HashSet of the values for this purpose.
I agree with JoniK. This can be done in a single line like this.
if(hashM.values().containsAll(arrayL)) {// put your code here that will be returned}
Needs:
Storing objects of a class which overrides equals and hash code
Will be looping and shoving objects into the datastructure
Need to be able to call contains to check whether a certain object is stored in the structure
If contains returns true then fetch that specific object from the structure and call a certain getter on that object
Options I've considered:
Map - this works for all the needs but I don't really have a map (key and a value). all I have is bunch of objects. Would it be a good practice to forcefully use a map by storing objects as key and integer or something in the value?
Set would work, however, it doesn't have a fetch method like get.
List would also work, but it doesn't have a method to fetch that is non index based. Meaning, once contains returns true I'll have to loop through the list to find the index of my particular object and then fetch it.
I'm open to using different libraries like apache commons or guava for example.
List would also work, but it doesn't have a method to fetch that is non index based.
List has an indexOf(Object) method which will do exactly what you want.
Although the best thing to use in this scenario would be a Map, because it offers fast retrieval based on Key-Value pair.
But List also allows to fetch data based on index.
So, you can use either a List or a Map. But to make your task easier, I would prefer a Map. Because i case of Map you won't have to search for an index of an Object, then get the Object at that index. Fetching is just a one-line operation.
// When using a List.
List<String> myList = new ArrayList<String>();
if (myList.contains("rohit")) {
myList.get(myList.indexOf("rohit"));
}
// When using Map.
Map<String, String> myMap = new HashMap<String, String>();
// You can directly fetch your object, based on some Key if you have one..
myMap.get("key");
You need a set. You don't need a fetch method (you think you do), because like you said you only have a bunch of objects. And since these use equals and hashCode, a set is exactly what you need.
Of course a map could do as well, because its keys is a set as well, but in the end you need to better specify your requirements, as it appears you are a bit confused as to the purpose of your data structure. From what I understand, you do not need a map indeed.
A hash set implementation will do. Here is what you can do with it all:
class Foo
{
final String name;
Foo(String name)
{
this.name = name;
}
boolean equals(Object obj)
{
return (obj instanceof Foo) && ((Foo)obj).name.equals(name);
}
}
Set<Foo> fooSet = new HashSet<Foo>();
fooSet.add(new Foo("someFoo"));
assert fooSet.contains(new Foo("someFoo"));
I have a need to store a list of dynamically created objects in a way where they can all be retrieved and their methods called on demand.
As far as I can see for the list and creation, a HashMap fits my needs but i'm a bit puzzled on recalling the objects and calling their methods using the HashMap.
Just as a reference, let me give you a little code:
Here is the HashMap:
Map<String, Object> unitMap = new HashMap<String, Object>();
// here is how I put an object in the Map notice i'm passing coordinates to the constructor:
unitMap.put("1", new Worker(240, 240));
unitMap.put("2", new Worker(240, 240));
Now I need to create a method that retrieves every object in the hashmap and call a method from each object. is this possible or can the created objects only be referenced directly. If so, is there another way to call a method of all existing instances of a class dynamically (in other words, on user input)?
Sure. You can do this:
for (Object thing : unitMap.values()) {
// use "thing" here
}
If you need the keys too, you can either get just the keys:
for (String key : unitMap.keySet()) {
// use "key" here
}
or both the keys and values together:
for (Map.Entry<String, Object> entry : unitMap.entrySet()) {
// use "entry.getKey()" and "entry.getValue()"
}
In all the above cases, each entry in the map is traversed one by one. So at the end of the loop, you'll have processed all the entries in the map.
If all of the values in the Map are Worker objects, you should declare your map to be of type Map<String, Worker>. This way, when you pull a value out of the map, it will be typed as a Worker. This way you can call any method declared on Worker as opposed to having to check the type at runtime using instanceof.
If the map holds different values, and you need to keep the value type as Object, it may be advantageous to use an interface to define the method that you want to call for each different object type.
If you do not know what method you want to run on the values until runtime, and the map can hold different values, you will just have to do what you are currently doing, and use Map<String, Object>.
Finally, to get the values of the map, you do just as Chris Jester-Young mentioned before me. The biggest advantage, as I said previously, is that your objects will be typed, and you will have no need for casting/instanceof checking.
I use this to put all values from hashMap on a List, hope it helps.
private List<String> getValuesFromHashMap(HashMap<String, String> hashMap) {
List<String> values = new ArrayList<String>();
for (String item : hashMap.values()) {
values.add(item);
}
return values;
}