Using Guava, is it possible to add new items to a Collection instaed of only transforming a Collection?
Imagine e.g. I have
Set<Integer> numbers = Sets.newHashSet(1,2,3);
Now, in addition to the already present numbers, also the double and triple of each number shall be included, therefore 2,4,6 as well as 3,6,9.
Is there something in Guava like
addToSet(numbers, <a function returning a List of values for each element in numbers>)
?
Thanks for any hint!
Why would something like Set.addAll(Collection c) not suffice?
Set<Integer> numbers = Sets.newHashSet(1,2,3);
numbers.addAll(setReturningFunction());
Decorate the Set (could use a ForwardingSet) and then override the add method to add the additional items into the backing delegate.
transformAndConcat does the job, allows returning more than one element, though only one element was passed to the transform function.
Related
As the title implies, I'd like to know how to insert different values into my ArrayList, without using too much space for several "add" functions.
ArrayList<Integer> arr = new ArrayList<Integer>(Arrays.asList(3,4));
ArrayCheck.allDivisibleBy(arr, divisor);
I have got an arraylist called arr, and I don't know if this is the right way to add several values (3,4) that way.
Furthermore I would also like to check the values in another method called allDivisbleBy. The function of this method is not relevant though, but I want to check the values and am not sure if "ArrayCheck" is a way to send the array values to the method.
The simplest way is to use Arrays.asList(arr). As expected, that static method returns a List with as it's contents the elements of the array.
I don't know if this is the right way to add several values (3,4) that
way
Yes it is. Else you can use this:
ArrayList<Integer> arr = new ArrayList<Integer>(2);
arr.add(3);
arr.add(4);
I want to check the values and am not sure if "ArrayCheck" is a way to
send the array values to the method
ArrayCheck is not a standard java class.
Check all of your inputs for your condition, put them in a Collection and use method addAll instead of add to add all of collection items at once.
I need to store unique objects in some datastructure, but also I need access by index like in ArrayList or plain array. Maybe there is some elegant way to do this without using convertions from set to array, iteration through all elemnts, checking value while adding to ArrayList and others.
I would be grateful for any help and advices.
You should have a look at ListOrderedSet from Apache Commons Collections:
Decorates another Set to ensure that the order of addition is retained and used by the iterator.
If an object is added to the set for a second time, it will remain in the original position in the iteration. The order can be observed from the set via the iterator or toArray methods.
The ListOrderedSet also has various useful direct methods. These include many from List, such as get(int), remove(int) and indexOf(int). An unmodifiable List view of the set can be obtained via asList().
Make your own class containing a HashSet<T> and an ArrayList<T>. For the add/append operation, if the element is not already in the set, append it to the list and add it to the HashSet. You'll use about twice as much memory as a normal ArrayList, but you'll get O(1) random access and contains operations.
I have a multiset in guava and I would like to retrieve the number of instances of a given element without iterating over this multiset (I don't want to iterate because I assume that iterating takes quite some time, as it looks through all the collection).
To do that, I was thinking first to use the entryset() method of multiset, to obtain a set with single instances and their corresponding count. Then, transform this set into a hashmap (where keys are the elements of my set, and values are their instance count). Because then I can use the methods of hashmap to directly retrieve a value from its key - done! But this makes sense only if I can transform the set into the hashmap in a quick way (without iterating trhough all elements): is it possible?
(as I said I expect this question to be flawed on multiple counts, I'd be happy if you could shed light on the conceptual mistakes I probably make here. Thx!)
Simply invoke count(element) on your multiset -- voila!
You may know in Guava Multiset is an interface, not a class.
If you just want to know the repeated number of an element, call Multiset.count(Object element).
Please forget my following statement:
Then if you are using a popular implementation HashMultiset, there is already a HashMap<E, AtomicInteger> working under the scene.
That is, when the HashMultiset iterates, also a HashMap iterates. No need to transform into another HashMap.
What changes to be done in ArrayList to make it behave like a Set (means it should not accept any duplicate values).
There are many ways to accomplish this. Here are a two:
Store the elements of the ArrayList in random order. When inserting a new value, do a linear scan over the elements and see if the element you're adding already exists. If so, don't add it. Otherwise, append it to the elements.
Enforce that the elements of the ArrayList always be stored in sorted order. To insert a new element, do a binary search to find where that element should be placed, and if the element already exists don't insert it. Otherwise, insert it at the given position.
However, you shouldn't be doing this. These approaches are very slow compared to HashSet or TreeSet, which are specialized data structures optimized to handle this efficiently.
Create your own implementation , implement java.util.List
override add(), addAll() , make use of contains()
As the others said, it's unclear why you need this.
Maybe LinkedHashSet is what you need?
http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
Other than already said, you could have a look at java.util.concurrent.CopyOnWriteArraySet. If you leave the "CopyOnWrite" part away, you have your ArraySet.
I have a list of objects which I want to perform an operation on. However I firstly need to divide the list into separate lists such that all items with the same parentID are in the same list, and then the operation is performed on each list separately (the reason being that the operation takes the parentID of the objects as a parameter).
What is the best way to separate a list based on a given property of it's elements, as required here? The highest number of objects that will be passed in the original list is < 10,000 and normally will be < 1,000.
All help is much appreciated!
It sounds like you might want to use Multimaps.index from Guava. That will build you a multi-map, where each key has a collection of elements.
The keyFunction passed into index would be a Function which just retrieves the property from a single element.
Create a
Map <IdType, List<YourObject>> map
loop thru the list, and for each id do something like
List theList = map.get(id);
if (theList == null ) {
// create a new list, add it to the map under the id
}
// add the item to theList
then you can loop thru the map's entries and you have a list of objects for each id. This approach does not require you to know how many different ids are in your list to begin with....
I would recommend writing an Iterator that wraps an Iterator, returning only elements that match what you want. You could then write an implementation of Iterable that takes an Iterable, returning such an iterator (this would allow you to use an enhanced for loop).
If you're okay with adding a 3rd party library, Google's Guava supplies various utilities which could help you out.
Specifically, use Collections2.transform like this:
Collection myOriginalList;
Collection mySplitList1 = Collections2.transform(myOriginalList, new Function() { /* method to filter out parent ID 1 */ });
... // repeat for each parent id you're interested in