I have a List of object and the list is very big. The object is
class Sample {
String value1;
String value2;
String value3;
String value4;
String value5;
}
Now I have to search for a specific value of an object in the list. Say if value3=='three'
I have to return those objects (My search is not always based on value3)
The list is
List<Sample> list = new ArrayList<Sample>();
What is the efficient way of doing it?
Thanks.
This question is related to
java
list
search
collections
I modifie this list and add a List to the samples try this
Pseudocode
Sample {
List<String> values;
List<String> getList() {
return values}
}
for(Sample s : list) {
if(s.getString.getList.contains("three") {
return s;
}
}
As your list is an ArrayList
, it can be assumed that it is unsorted. Therefore, there is no way to search for your element that is faster than O(n).
If you can, you should think about changing your list into a Set
(with HashSet
as implementation) with a specific Comparator
for your sample class.
Another possibility would be to use a HashMap
. You can add your data as Sample
(please start class names with an uppercase letter) and use the string you want to search for as key. Then you could simply use
Sample samp = myMap.get(myKey);
If there can be multiple samples per key, use Map<String, List<Sample>>
, otherwise use Map<String, Sample>
. If you use multiple keys, you will have to create multiple maps that hold the same dataset. As they all point to the same objects, space shouldn't be that much of a problem.
If you always search based on value3
, you could store the objects in a Map:
Map<String, List<Sample>> map = new HashMap <>();
You can then populate the map with key = value3
and value = list of Sample objects with that same value3
property.
You can then query the map:
List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");
Note: if no 2 Sample
instances can have the same value3
, you can simply use a Map<String, Sample>
.
With Java 8 you can simply convert your list to a stream allowing you to write:
import java.util.List;
import java.util.stream.Collectors;
List<Sample> list = new ArrayList<Sample>();
List<Sample> result = list.stream()
.filter(a -> Objects.equals(a.value3, "three"))
.collect(Collectors.toList());
Note that
a -> Objects.equals(a.value3, "three")
is a lambda expressionresult
is a List
with a Sample
typelist.parallelStream()
instead of list.stream()
(read this)If you can't use Java 8, you can use Apache Commons library and write:
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
Collection result = CollectionUtils.select(list, new Predicate() {
public boolean evaluate(Object a) {
return Objects.equals(((Sample) a).value3, "three");
}
});
// If you need the results as a typed array:
Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]);
Note that:
Object
to Sample
at each iterationSample[]
, you need extra code (as shown in my sample)Bonus: A nice blog article talking about how to find element in list.
Source: Stackoverflow.com