java : queue with maximum capacity [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Size-limited queue that holds last N elements in Java
Java - Ring Buffer
I am interested in a bounded above queue, that whenever faced with object insertion, would remove the oldest object first, if the insertion would result in 'overflowing'. I want the addition to be O(1) and the memory usage as little as possible. I was thinking about either overriding add method on LinkedList, but ideally I would implement a circular, array based list, with catching front/back pointer. Whenever the addition is made over capacity, front pointer advances, and then the back one. Is there an implementation similar to this?

A linked list is a waste of memory, since the next pointer uses mem, that the ArrayList does not.
The performant implementations are based on ArrayList or better on an array.
If your circular buffer size is fixed, you would use an array.
I implemented a circular buffer using an internal array, with start and end position index vars. I did not found an implemnetation of a circular list / buffer, that did that what i wanted.
It was not dificullt to implement, but i recomend using a high number of unit test cases, to prove that your circ buffer works as expected.

Related

What is the benefit of setting the capacity of an ArrayList explicitly [duplicate]

This question already has answers here:
Why start an ArrayList with an initial capacity?
(11 answers)
Closed 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
In java ArrayList we have a constructor -
ArrayList(int capacity)
and two methods -
void ensureCapacity(int minCapacity)
void trimToSize()
Consider a code-sample:
ArrayList<String> arrayList3 = new ArrayList<>(5);
System.out.println(arrayList3.size());
arrayList3.add("Zebra");
arrayList3.add("Giraffe");
arrayList3.add("Bison");
System.out.println(arrayList3);
System.out.println(arrayList3.size());
arrayList3.add("Rhino");
arrayList3.add("Hippo");
arrayList3.add("Elephant");
arrayList3.add("Antelope");
System.out.println(arrayList3);
System.out.println(arrayList3.size());
Output:
0
[Zebra, Giraffe, Bison]
3
[Zebra, Giraffe, Bison, Rhino, Hippo, Elephant, Antelope]
7
Here, I fail to see how setting an initial capacity affects the execution of the program. ArrayList is a flexible list that changes size as per demand. So what is the significance of setting the capacity explicitly?
And in the case if I want to set the capacity explicitly, is there any method to view the current capacity? Since int size() clearly is not applicable here.
ArrayList as an implementation of a Dynamic array data structure.
It resizes when its underlying array gets full (i.e. the current list index exceeds the last valid index of the underlying array).
When it happens, method add() (or addAll) internally will invoke the method grow(). Which will double the capacity. I.e. it will create a new array with the length two times bigger than the previous length plus a number of new elements that don't fit into the current size.
The growth has a cost of O(n) because all previously added elements need to be copied into the new array.
Reminder: when resizing isn't required, a new element will be added in constant time O(1).
No-argument constructor creates an ArrayList with capacity of 10.
If you expect that a newly created ArrayList would eventually contain let's say 50,000 elements, it makes sense to use an overloaded constructor to provide the initial capacity of 50,000 in order to improve performance by avoiding unnecessary resizing.
Also, for that you can use method ensureCapacity() which accessible in the ArrayList class (not in the List interface, because the notion of capacity isn't applicable to LinkedList which isn't backed by an array).
is there any method to view the current capacity
No, there isn't. That's called encapsulation. ArrayList, StringBuilder, HashMap, etc. are backed by a plain array, but they will not allow interacting with their underlying array directly.
But if you have a case when array initially increases size and then a lot of elements are being removed, and you want to release unoccupied heap space, you can use method trimToSize():
Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.
But it has to be used with caution, because it can lead to cyclic growth and trimming, which will cause performance degradation.
Note that there's no need to worry about the amount of unoccupied space if the list is moderate in size, or if you are not expecting let's say 80% of the data to be removed in one go. I.e. even if the list is huge but 50% of its elements gets removed, and you apply trimToSize() on it, it'll restore its previous capacity with the next added element - that's the scenario of continuously growing and shrinking list which will perform badly.
As a possible option, if you heave a case when most of the data can be removed from a list, instead of using trimToSize() you can filter out the elements that have to be preserved, place them into a new list and dereference the previous one.

Stack implementation java - LinkedList vs Vector [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I wanted to know why Stack is implemented using Vector and not with LinkedList. As far as I know, LinkedList provides more efficient structure for deletion and insertion of elements. So, why stack is implemented using vector and not LinkedList. Java implements Queue interface with LinkedList and since in both stack and queue, insertion and deletion is the primary function, why not linkedlist for Stack.
Stack and Vector are both old classes.
If you read the Javadoc of Stack, you'll see that it suggests using Deque instead:
A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class.
And LinkedList does implement the Deque interface.
As far as I know, LinkedList provides more efficient structure for deletion and insertion of elements.
That is not actually true ... in the context of stack operations. (Or in general).
A Vector is a form of array list. It works by allocating an array to hold a number of elements, and using array indexing to access and update the list. Insertion and deletion at a random position in the Vector is expensive because it entails copying multiple element references.
However, that not what a Stack requires. It actually requires insertion and deletion exclusively at the end of the Vector, and that is cheap. In most cases, insertion and deletion simply involves assigning an element into an array cell and adjusting the Vector object's length field. It only gets expensive if there is not enough space in the array. Then the array has to be "grown" by creating a new one and copying the elements. But when an array list grows the array exponentially (e.g. by doubling its size), the math says that the amortized cost is O(1) over the lifetime of the array list.
By contrast, every time you insert an element into a LinkedList, it involves allocating a new internal "node" object to hold the element. That is more expensive on average than a Vector insertion, especially when you take into account the GC costs incurred over the lifetime of the "node" object.
It also turns out a LinkedList uses up to 4 times as much memory per element as a Vector does, assuming we are using 64 bit references.
In short, a Vector is more efficient and uses less space than a LinkedList for a stack data structure. The correct design choice was made1.
1 - As you would expect. We can assume that the engineers who designed and maintained Java over the last ~25 years knew what they were doing. Or that the tens of thousands of other people who have looked at that code since it was written would also have noticed a (hypothetical!) mistake of that magnitude and logged a bug report.

What's the difference between Stream.builder() and calling stream() on an ArrayList in Java?

Is there any difference between using Stream.builder() versus creating an ArrayList and then calling stream() on it?
This is an implementation detail, but yes, the builder is better optimized to the use case of being incrementally filled, followed by an operation streaming over the contained elements.
In contrast, an ArrayList has to support arbitrary modification and random access.
So, when repeatedly adding elements to an ArrayList without specifying a correctly predicted initial capacity, it may need to allocate a new, larger array and copy the current array into it whenever the current capacity is exhausted.
In contrast, the builder has a special support for the single element case, which doesn’t need an array at all. Then, if more elements are added, it will turn to a spined buffer. This buffer starts with a small array like ArrayList but when its capacity is exhausted, it begins to use an array of arrays instead of repeatedly copying the array to a larger flat array.
So this saves the copying costs you’d have when filling an ArrayList. You can save these costs for ArrayList by specifying the right initial capacity, but that only works when an estimate is available. Specifying an initial capacity also removes the optimization for the empty case. So generally, the stream builder can deal with unknown sizes much better.
Another property of this design is that Stream.Builder can deal with more than 2³¹ elements, unlike ArrayList, if you have enough memory.
Stream.builder() is not a terminal operation, so it's lazy. Using the second one, in theory, uses more memory. From the Stream.Builder Javadoc, This allows the creation of a Stream by generating elements individually and adding them to the Builder (without the copying overhead that comes from using an ArrayList as a temporary buffer.)

List.toArray(Object[]) performance [duplicate]

This question already has answers here:
.toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
(8 answers)
Closed 4 years ago.
I'm getting a List of object A, then I use Apache Commons Collection4 to transform the obtained List from having A instances to having B instances.
listOfBs = (List<B>) CollectionUtils.collect(listOfAs, componentTransformer);
However, eventually I need to have an Array of Bs not a List.
So my question is, which is faster.
Convert the list using CollectionUtils.collect
Create an array using listOfBs.toArray(new B[listOfBs.size()])
Or
Loop over the listOfAs
Transform each A object to a B object
Add each B object to an array (B[])
The difference between the first approach and the second approach is that the first approach has much less code, but I'm not sure if the toArray method bares a hidden loop or expensive operations.
What I see in the second approach is that I'm sure I'll loop only once over the listOfAs list.
So which approach is faster ?
Don't be concerned about performance of List.toArray(), its complexity is linear as it will resort to a single loop internally.
As it is implemented with Arrays.copyOf, which eventually comes to System.arraycopy, that is implemented in native code it could be potentially even faster than a java-level loop.
Very interesting to read is this article:http://shipilev.net/blog/2016/arrays-wisdom-ancients/#_conclusion
It goes into great detail about the different ways to convert a List to an array.
Conclusion: do not use listOfBs.toArray(new B[listOfBs.size()]) as stated by you, but use listOfBs.toArray(new B[0]).
Believe it or not, this is faster.

ArrayList in Java when storing large objects

I came across this interview question about arraylist in Java, and I feel it is quite interesting but no clue how to answer it:
What attention should be paid when using arrayList to store large object?
I wonder if we should answer this question in the regard of time/space coplexity?
Thanks
All objects in Java are stored as references, in containers and variables, etc, so in C++ terms, all containers only store pointers to the objects. In such a situation, the size of the object should be irrelevant for most if not all use cases.
Internally ArrayList uses Object[]. Once it reaches max capacity, it creates a new array of size 1.5 times the original and will copy from old array to new array. May be interviewer wanted to check about the cost of this copy with large objects
ArrayList: how does the size increase?
check ensureCapacity() - http://www.docjar.com/html/api/java/util/ArrayList.java.html
ArrayList supports dynamic arrays that can grow as needed.
In Java, arrays has a fixed length this means after the arrays are created, they cannot grow or shrink, which means that you must know in advance how many elements an array will hold. But, sometimes, you may dont know the size until the runtimeso that in this situation we used ArrayList.
ArrayList can dynamically increase or decrease in size. Array lists are created with an initial size. When this size is exceeded, the collection is automatically enlarged. When objects are removed, the array may be shrunk.
also, be aware that Arraylist store only objects.

Categories

Resources