Which collection in java enables insterting between elements - java

I would like to use colllection(List like one) in java which enables inserting between to elements?

Collections that are derivative of List contain an add method that takes an index so you can do this. java.util.ArrayList is a common one...

Use add method of List
to specify the position where you want to insert in a list

Adding an element between elements is an optional operation, which by default in AbstractCollection is not implemented and throws a specific exception. Derived by AbstractCollection, AbstractList was added with out of the box implementation for add(int, E) so any concrete implementation of AbstractList will have it.
More important, choose an implementation that fit your needs of performance regarding memory consumption, reads, writes, etc...

The List interface has a function add(index,element) which adds an element at the specified index.
ArrayList<String> list=new ArrayList<String>();
list.add("Java") ;
list.add("JSP") ;
list.add("STRUTS") ;
list.add("EJB") ;
list.add(2,"C++");

The list interface declares a function add(int index, E element).
The ArrayList, LinkedList class has implementations for the above method. So can use either one of the above as per your requirement to add an element in between.
List os = new ArrayList();
os.add('Windows');
os.add('Linux');
os.add('Mac');
os.add(1,'Android')
Android will be added at the 1st index of the list i:e will be the 2nd element as index begins with 0.

You can use the add(int index, Integer element) function of the list.
In this function, you can specifically put the element in the range of list using the index value.
Here is the sample:
List<Integer> sampleList = new ArrayList<Integer>();
sampleList.add(1);
sampleList.add(2);
sampleList.add(3); //sampleList now contains {1,2,3}
Now if you want to put it between 1 and 2.
sampleList.add(1,4); //sampleList now contains {1,4,2,3}
We put the value 4 between 1 and 2.

Array List is the best way to Insert/Update/Delete like operations easily.
And also you can use Linked List for that but it is used mostly for large data.

Related

Java - Data structure design - Fixed size, random access, thread safe, sorted collection

So, in some question I was required to implement the following:
Data structure of fixed size (n=10), that is always ordered (descending, not that it matters), thread safe, and supports random access.
My solution was - using a TreeSet, whenever adding an element, if there are already n elements, remove the smallest element (if the new element if bigger than it) and add the new element. Otherwise, just add the new element.
When accessing a random index, use the TreeSet iterator to iterate until the required index.
I don't like this solution so much. So I thought of another solution:
Using an ArrayList, constructed with the size of n. Whenever trying to add an element, do a Collections.binarySearch() for the element and insert it if it doesn't exists, using the index returned from binarySearch. If after adding the element the list length is bigger than n (equals n+1 actually), remove the smallest element (which is on the end of the list). This way, we get log(n) for add (same as TreeSet from previous solution) and random access is O(1). Only thing I don't like about it is that the add() for an arbitrary index in the middle of the list requires shifting all the elements after it. (works well for small n but for big n maybe not?)
For both solutions I use ReentrantReadWriteLock - acquire writeLock() for add and readLock() for the get() / read operations.
Is there a better solution?
**
Collections.synchronizedList(List i) makes the passed argument a threadsafe List.
you can implement the comparable interface when creating your class and override compareTo() method in a way that it orders the element by descending order when you are adding them to the ArrayList<>() or you can go for Comparator class and overriding compare() method while sorting it.
In the total collection, only List(I) supports RandomAccess.
ArrayList<Employee> arrayList = Collections.synchronizedCollection(new ArrayList<Employee>(10));
and if you want the same item should not be added to the ArrayList use Comparator and return 0 when a new item (want to add) and last item (already added) is equal. handle the return value in such a manner that if (...==0){ don't add to the data ) else { add it }.
I hope I could give u some hint.

Java equivalent of Python List

In Python there is a data structure called 'List'. By using 'List' data structure in Python we can append, extend, insert, remove, pop, index, count, sort, reverse.
Is there any similar data structure in Java where we can get all that function like Python List?
The closest Java has to a Python List is the ArrayList<> and can be declared as such
//Declaring an ArrayList
ArrayList<String> stringArrayList = new ArrayList<String>();
//add to the end of the list
stringArrayList.add("foo");
//add to the beggining of the list
stringArrayList.add(0, "food");
//remove an element at a spesific index
stringArrayList.remove(4);
//get the size of the list
stringArrayList.size();
//clear the whole list
stringArrayList.clear();
//copy to a new ArrayList
ArrayList<String> myNewArrayList = new ArrayList<>(oldArrayList);
//to reverse
Collections.reverse(stringArrayList);
//something that could work as "pop" could be
stringArrayList.remove(stringArrayList.size() - 1);
Java offers a great selection of Collections, you can have a look at a tutorial that Oracle has on their site here https://docs.oracle.com/javase/tutorial/collections/
IMPORTANT: Unlike in Python, in Java you must declare the data type that your list will be using when you instatiate it.
Several collections exist, but your probably looking for ArrayList
In Python you can simply declare a list like so:
myList = []
and begin using it.
In Java, it better to declare from the interface first so:
List<String> myList = new ArrayList<String>();
Python Java
append add
Remove remove
len(listname) list.size
Sorting a List can require a little more work, for example, depending on the objects you may need to implement Compactor or Comparable.
ArrayList will grow as you add items, no need to extend it on your own.
As for reverse() and pop(), I'll refer you can refer to:
How to reverse a list in Java?
How to pop items from a collection in Java?
Java has an interface called list, which has implementations such as ArrayList, AbstractList, AttributeList, etc.
https://docs.oracle.com/javase/8/docs/api/java/util/List.html
However, each one has different functionalities, and I don't know if they have everything you've specified such as .reverse().
Take a look at Collections in java. There are many lists (ArrayList, LinkedList etc). Choose the best datastructure needed for the requirement and complexity (both space and time).

Java Collection (LinkedList Concepts)

When I declare LinkedList like:
List<String> names = new LinkedList<String>();
it does not support any of the LinkedList's special methods (ex: names.peekLast(), names.pollFirst() )
But when I declare like:
LinkedList<String> names = new LinkedList<String>();
then it supports these methods.
Yes, it is obvious that reason is the reference, as LinkedList contains that's methods and List does not have!
But my question is that when I want to work with LinkedList, which one is better and correct? Or what is the usage of them?
If you need to use LinkedList methods that don't exist in List, you should use a LinkedList reference (you could use a List reference and cast to LinkedList in order to call LinkedList specific methods, but that would make less sense).
Otherwise, it is preferable to use the List interface for holding the reference, since it makes your code more generic, since it won't depend on any specific List implementation.
Well, List is basically backed by an array which is usually bigger than the current number of items. The elements are put in an array, and a new array is created when the old one runs out of space. This is fast for access by index, but slow at removing or inserting elements within the list or at the start. Adding/removing entries at the end of the list is reasonably cheap.
LinkedList is a doubly-linked list - each node knows its previous entry and its next one. This is fast for inserting after/before a particular node (or the head/tail), but slow at access by index.
LinkedList will usually take more memory than List because it needs space for all those next/previous references - and the data will probably have less locality of reference, as each node is a separate object. On the other hand, a List can have a backing array which is much larger than its current needs.
Reference from Difference between List<T> and LinkedList<T>
You can also refer to oracle docs
Linked List
All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.
List
The List interface provides four methods for positional (indexed) access to list elements. Lists (like Java arrays) are zero based. Note that these operations may execute in time proportional to the index value for some implementations (the LinkedList class, for example). Thus, iterating over the elements in a list is typically preferable to indexing through it if the caller does not know the implementation.
Well there is very simple explanation regarding that is List<> is like array which is making new array when its running out of space. And LinkedList<> is like doubly-linked list where each an every node will have link of previous node as well as next node.
More of that you can search from oracle docs
https://docs.oracle.com/javase/7/docs/api/java/util/List.html
and
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
You can differentiate by your self. :)

Java - How to separate a list based on a property of it's elements

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

Cost of inserting element at 0th position of LinkedHashSet?

I'm using LinkedHashSet. I want to insert items at the 0th position, like:
Set<String> set = new LinkedHashSet<String>();
for (int i = 0; i < n; i++) {
set.add(0, "blah" + i);
}
I'm not sure how linked hash set is implemented, is inserting going to physically move all addresses of current items, or is it the same cost as inserting as in a linked-list implementation?
Thank you
------ Edit ---------------
Complete mess up by me, was referencing ArrayList docs. The Set interface has no add(index, object) method. Is there a way to iterate over the set backwards then? Right now to iterate I'm doing:
for (String it : set) {
}
can we do that in reverse?
Thanks
Sets are, by definition, independent of order. Thus, Set doesn't have add(int , Object) method available.
This is also true of LinkedHashSet http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
LinkedHashSet maintains insertion order and thus all elements are added at the end of the linked list. This is achieved using the LinkedHashMap. You can have a look at the method linkEntry in LinkedHashMap http://www.docjar.com/html/api/java/util/LinkedHashMap.java.html
Edit: in response to edited question
There is no API method available to do this. But you can do the following
Add Set to a List using new ArrayList(Set)
Use Collections.reverse(List)
Iterate this list
Judging by the source code of LinkedHashMap (which backs LinkedHashSet -- see http://www.docjar.com/html/api/java/util/LinkedHashMap.java.html ), inserts are cheap, like in a linked list.
To answer your latest question, there is no reverse iterator feature available from LinkedHashSet, even though internally the implementation uses a doubly linked list.
There is an open Request For Enhancement about this:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4848853
Mark Peters links to functionality available in guava, though their reverse list actually generates a reverse list.
As already mentioned, LinkedHashSet is build on LinkedHashMap, which is built on HashMap :) Javadocs says that it takes constant time to add an element into HashMap, assuming that your hash function is implemented properly. If your hash function is not implemented well, it may take up to O(n).
Iteration backwards in not supported at this moment.
You can't add elements to the front of a LinkedHashSet... it has no method such as add(int, Object) nor any other methods that make use of the concept of an "index" in the set (that's a List concept). It only provides consistent iteration order, based on the order in which elements were inserted. The most recently inserted element that was not already in the set will be the last element when you iterate over it.
And the Javadoc for LinkedHashSet explicitly states:
Like HashSet, it provides constant-time performance for the basic operations (add, contains and remove), assuming the hash function disperses elements properly among the buckets.
Edit: There is not any way to iterate over a LinkedHashSet in reverse short of something like copying it to a List and iterating over that in reverse. Using Guava you could do that like:
for (String s : Lists.reverse(ImmutableList.copyOf(set))) { ... }
Note that while creating the ImmutableList does require iterating over each element of the original set, the reverse method simply provides a reverse view and doesn't iterate at all itself.

Categories