How to add an element to an ArrayList - java

how can i make a user enter a number, which will then shift the array to the right 1. the array cant exceed 50. please help, thanks in advance :)
List<Integer> list = new ArrayList<Integer>(1);
public void add(int value) {
list.add(0, value);
for(int i = 0; i < array.length; i++) {
list.add(index, value); // how to make the elements shift to the right?
if(list.size > 50) {
list.remove(50);
}
}
}

List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size() == 50)
list.remove(list.size() -1);
list.add(value);
}

ArrayList shifts elements for you, that's why it has index, look at this answer.
When you create the ArrayList: new ArrayList<Integer>(50) 50 dont define size, define capacity of the ArrayList. When created is empty and size is 0.
List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size <= 50) list.remove(list.size() - 1);
// inserting element at position 0 shifts other elements
list.add(0, value);
}

public class TestList {
public static void main(String[] args) {
ArrayList<Integer> arrlist = new ArrayList<Integer>(4);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(4);
arrlist.add(5);
// adding element 25 at third position
arrlist.add(2,25);
for (Integer number : arrlist) {
System.out.println("List Value = " + number);
}
}
}

Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). From this "http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html"
so you need just to check if the size of your list is no longer than 50, and add the number in the specified index.
List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size() == 50) // if the size of the array is 50, then remove the last value.
list.remove(list.size() -1);
list.add(int index, E element);// you can even choose where position to insert your value.
}

In the constructor part what you have defined is the capacity. The default minimum capacity is 10. You know your array cant exceed to 50. There is a chance that there must be less element then 50. So first remain that constructor part empty.
List<Integer> list = new ArrayList<Integer>();
public void add(int value) {
if(list.size() <50)
list.add(0,value);
else
{
list.remove(list.size()-1);
list.add(0, value);
}

private List<Integer> list = new ArrayList<Integer>(51);
public void add(int value) {
list.add(0, value); //other elements are shifted right, you need do nothing else
//then limit the list to 50 elements
while(list.size() > 50) list.remove(list.size() - 1);
}
I can't see the rest of the code. I don't know what list length is before add so I'm just guaranteeing it's <= 50 after with a while.
You can specify an initial capacity, if you do, use 51 not 50. It gives the array an initial size that can hold your 50, plus the 51st which is in list for a short period before removal.

Related

Why is a negative index value taken while inserting a new element into an java array?

I was trying out a java code to insert a new element into an array, I understand most of the program except for a line of code: "int newindex = -index-1;". Why does a negative sign used in front of the index?
Here is the full program:
public class ArrayManipulation2 {
public static void main(String[] args) {
int[] array = {6,3,5,2,-9,-5,-1,0};
Arrays.sort(array);
printArray(array);
int index= Arrays.binarySearch(array, 1);
int newindex = -index-1;
array = insertElement(array, 1, newindex);
printArray(array);
}
public static void printArray(int[] array){
for(int i=0; i<array.length; i++){
if(i!=0){
System.out.print(", ");
}
System.out.print(array[i]);
}
System.out.println();
}
public static int[] insertElement(int[] orginal, int element, int index){
int length = orginal.length;
int[] destination = new int[length+1];
System.arraycopy(orginal, 0, destination, 0, index);
destination[index]=element;
System.arraycopy(orginal, index, destination, index+1, length-index);
return destination;
}
}
I need to know why the new index is specified as "-index-1"?.
Arrays.binarySearch() returns a negative value if the item isn't already in the array, so that it can distinguish between where the item is if it is there and where it should be if it isn't there.
The code isn't correct without catering for the case where the result is positive.
Background:
The method Arrays.binarySearch() returns
the index of the search key, if it is contained in the array; otherwise, (-(insertion point) – 1). The insertion point is defined as the point at which the key would be inserted into the array: the index of the first element greater than the key, or a.length if all elements in the array are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.
So, this API suggested be used in a sorted array, otherwise it could return unexpected return value
Then ,let me clarify the code :
If can not find the element, the method will return value "(-(insertion point) – 1)" , then get its "opposite number",so the value could be insertion+1, and then minus 1, we can get its right insert position

How to check if an array is filled enough in java?

I want to check if an array is at 75% filled with objects and if it's true i have to resize it. In the variable size i have my objects (!=null) and i have an array of integers ints
public class PQ {
private int[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new int[capacity + 1];
this.size = 0;
}
public void insert(int number) {
//Code
}
private int[] resize() {
int[] newPQ = new int[this.pq.length * 2];
for (int i = 0; i < this.pq.length; i++) {
newPQ[i] = this.pq[i];
}
return newPQ;
}
}
Try this:
Whenever you add an element, we increment size (this will track the number of non-empty spaces so that you don't need to continually recount your array). Then we compare this number to the total length of your array. If count is at least 75% of the size of the array, we call your resize method and set pq to the new array it returns. I assume that you wish to add to the end of the array, and that you don't want empty indexs between numbers. If you want gaps you will need to use a loop which I am trying to avoid for efficiency's sake, if it isn't necessary. Assuming you don't, you can just add to your array at index size since this will be the first non-empty element.
//O(1) efficiency if you don't need to resize, O(n) if you do
public void insert(int number) {
if(size / pq.length >= 75) {
pq = resize();
}
pq[size] = number; //Since this will be the first non-empty index
size++;
return; //Doing it this way, if you can, is much more efficient than looping
}
If you call remove and take out from anything but the end you are going to have to shift everything down so that you don't have empty space.
If you are going to have empty indexes, try something like this (to insert at the first empty index encountered by the loop)...Let's use an Integer[] instead so that you can check for null and don't have to worry about any 0's in the array being counted as empty (int[] initiates everything to 0).
That way we can check for empty space and 0's are not counted as empty space in case you use any in your int[].
//O(n) efficiency if you don't need to resize, O(n^2) if you do
public void insert(int number) {
if(size / pq.length >= 75) {
pq = resize();
//You would have to make resize return an Integer[] and
//implement this throughout the code
}
for(int i = 0; i < pq.length; i++) {
if(pq[i] == null) {
pq[size] = number;
size++;
return;
}
}
}
Regardless:
Remember when you call remove() to decrement size.
What you could do is have an integer instance variable called count, that keeps track of the number of elements in the pq array. And whenever you insert an element into the array through the insert method, you can increment the count variable. Whenever you remove an element from the array through a remove method, you can decrement the count variable. Then, you can use this to check if the array is 75% filled at least,
if(pq.length * .75 <= size){
//do what you need to do here
}
And the class would look like this,
public class PQ {
private int[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new int[capacity + 1];
this.size = 0;
}
public void insert(int number) {
size++;
//Code
}
public void remove(int number) {
size--;
//Code
}
private int[] resize() {
int[] newPQ = new int[this.pq.length * 2];
for (int i = 0; i < this.pq.length; i++) {
newPQ[i] = this.pq[i];
}
return newPQ;
}
}
You are explicitly storing the size as a variable. You also know the backing array's size. Compare them at the point when you need to check size: if(this.size > 3*this.pq/4).
Use ArrayList do everything automatically for you in more efficient way.
Edited:
it is the initialization, all put -1
this.pq = new int[capacity + 1];
Arrays.fill(pq, -1);
then when you check you do like this:
if(pq[pq.length*.75] != -1) {
// then is means that is has already filled up 75%
} else {
// not filled 75% yet
}

Java ArrayList initialization

I've been trying to understand the following code that uses Depth-First-Search (DFS) to print out all unique combinations of length k comprising of numbers [1..n]
Please see the line commented "doubt" in the private dfs function
public ArrayList<ArrayList<Integer>> combine(int n, int k) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if (n <= 0 || n < k)
return result;
ArrayList<Integer> item = new ArrayList<Integer>();
dfs(n, k, 1, item, result);
return result;
}
private void dfs(int n, int k, int start, ArrayList<Integer> item,
ArrayList<ArrayList<Integer>> res) {
if (item.size() == k) {
res.add(new ArrayList<Integer>(item)); /*doubt*/
return;
}
for (int i = start; i <= n; i++) {
item.add(i);
dfs(n, k, i + 1, item, res);
item.remove(item.size() - 1);
}
}
If I change it to res.add(item) it returns result as list of null lists. ListObject.add(E e) is a perfectly valid function, why doesn't it work here?
So your question concerns these two alternatives:
// works
res.add(new ArrayList<Integer>(item));
// won't work, results in empty lists
res.add(item);
The purpose of new ArrayList<Integer>(item) is to create a new list with the same content as the original, effectively cloning the original.
If you don't clone the original, it will stay empty. The first time dfs is called, item is empty, and then look at this loop:
for (int i = start; i <= n; i++) {
item.add(i);
dfs(n, k, i + 1, item, res);
item.remove(item.size() - 1);
}
Every element added to item will be later removed. This is why you end up with empty lists without the cloning step. Without cloning, not only you get a list of empty lists, all of the empty lists are actually the same original ArrayList that you created in combine, before the first call to dfs.
It's because item.remove(item.size() - 1); is modifying the same list that you just added to your list of results. So it always ends up removing all the items. The solution you have is actually copying the list of items and storing them in your result list. No one has a reference to that list so it doesn't get modified.

Fixed-size collection that keeps top (N) values in Java

I need to keep top N(< 1000) integers while trying to add values from a big list of integers(around a million sized lazy list). I want to be try adding values to a collection but that needs to keep only the top N(highest values) integers. Is there any preferred data structure to use for this purpose ?
I'd suggest to use some sorted data structure, such as TreeSet. Before insertion, check the number of items in the set, and if it reached 1000, remove the smallest number if it's smaller than the newly added number, and add the new number.
TreeSet<Integer> set = ...;
public void add (int n) {
if (set.size () < 1000) {
set.add (n);
} else {
Integer first = set.first();
if (first.intValue() < n) {
set.pollFirst();
set.add (n);
}
}
}
Google Guava MinMaxPriorityQueue class.
You can also use custom sorting by using a comparator (Use orderedBy(Comparator<B> comparator) method).
Note: This collection is NOT a sorted collection.
See javadoc
Example:
#Test
public void test() {
final int maxSize = 5;
// Natural order
final MinMaxPriorityQueue<Integer> queue = MinMaxPriorityQueue
.maximumSize(maxSize).create();
queue.addAll(Arrays.asList(10, 30, 60, 70, 20, 80, 90, 50, 100, 40));
assertEquals(maxSize, queue.size());
assertEquals(new Integer(50), Collections.max(queue));
System.out.println(queue);
}
Output:
[10, 50, 40, 30, 20]
One efficient solution is a slightly tweaked array-based priority queue using a binary min-heap.
First N integers are simply added to the heap one by one or you can build it from array of first N integers (slightly faster).
After that, compare the incoming integer with the root element (which is MIN value found so far). If the new integer is larger that that, simply replace the root with this new integer and perform down-heap operation (i.e. trickle down the new integer until both its children are smaller or it becomes a leaf). The data structure guarantees you will always have N largest integers so far with average addition time of O(log N).
Here is my C# implementation, the mentioned method is named "EnqueueDown". The "EnqueueUp" is a standard enqueue operation that expands the array, adds new leaf and trickles it up.
I have tested it on 1M numbers with max heap size of 1000 and it runs under 200 ms:
namespace ImagingShop.Research.FastPriorityQueue
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
public sealed class FastPriorityQueue<T> : IEnumerable<Tuple<T, float>>
{
private readonly int capacity;
private readonly Tuple<T, float>[] nodes;
private int count = 0;
public FastPriorityQueue(int capacity)
{
this.capacity = capacity;
this.nodes = new Tuple<T, float>[capacity];
}
public int Capacity => this.capacity;
public int Count => this.count;
public T FirstNode => this.nodes[0].Item1;
public float FirstPriority => this.nodes[0].Item2;
public void Clear()
{
this.count = 0;
}
public bool Contains(T node) => this.nodes.Any(tuple => Equals(tuple.Item1, node));
public T Dequeue()
{
T nodeHead = this.nodes[0].Item1;
int index = (this.count - 1);
this.nodes[0] = this.nodes[index];
this.count--;
DownHeap(index);
return nodeHead;
}
public void EnqueueDown(T node, float priority)
{
if (this.count == this.capacity)
{
if (priority < this.nodes[0].Item2)
{
return;
}
this.nodes[0] = Tuple.Create(node, priority);
DownHeap(0);
return;
}
int index = this.count;
this.count++;
this.nodes[index] = Tuple.Create(node, priority);
UpHeap(index);
}
public void EnqueueUp(T node, float priority)
{
int index = this.count;
this.count++;
this.nodes[index] = Tuple.Create(node, priority);
UpHeap(index);
}
public IEnumerator<Tuple<T, float>> GetEnumerator()
{
for (int i = 0; i < this.count; i++) yield return this.nodes[i];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DownHeap(int index)
{
while (true)
{
int indexLeft = (index << 1);
int indexRight = (indexLeft | 1);
int indexMin = ((indexLeft < this.count) && (this.nodes[indexLeft].Item2 < this.nodes[index].Item2))
? indexLeft
: index;
if ((indexRight < this.count) && (this.nodes[indexRight].Item2 < this.nodes[indexMin].Item2))
{
indexMin = indexRight;
}
if (indexMin == index)
{
break;
}
Flip(index, indexMin);
index = indexMin;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Flip(int indexA, int indexB)
{
var temp = this.nodes[indexA];
this.nodes[indexA] = this.nodes[indexB];
this.nodes[indexB] = temp;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UpHeap(int index)
{
while (true)
{
if (index == 0)
{
break;
}
int indexParent = (index >> 1);
if (this.nodes[indexParent].Item2 <= this.nodes[index].Item2)
{
break;
}
Flip(index, indexParent);
index = indexParent;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
The basic implementation is taken from "Cormen, Thomas H. Introduction to algorithms. MIT press, 2009."
In Java 1.7 one may use java.util.PriorityQueue. To keep the top N items you need to use reverse comparator, e.g. for integers you order them descending. In this manner the smallest number is always on top and could be removed if to many items in queue.
package eu.pawelsz.example.topn;
import java.util.Comparator;
import java.util.PriorityQueue;
public class TopN {
public static <E> void add(int keep, PriorityQueue<E> priorityQueue, E element) {
if (keep == priorityQueue.size()) {
priorityQueue.poll();
}
priorityQueue.add(element);
}
public static void main(String[] args) {
int N = 4;
PriorityQueue<Integer> topN = new PriorityQueue<>(N, new Comparator<Integer>() {
#Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
add(N, topN, 1);
add(N, topN, 2);
add(N, topN, 3);
add(N, topN, 4);
System.out.println("smallest: " + topN.peek());
add(N, topN, 8);
System.out.println("smallest: " + topN.peek());
add(N, topN, 5);
System.out.println("smallest: " + topN.peek());
add(N, topN, 2);
System.out.println("smallest: " + topN.peek());
}
}
// this Keep Top Most K Instance in Queue
public static <E> void add(int keep, PriorityQueue<E> priorityQueue, E element) {
if(priorityQueue.size()<keep){
priorityQueue.add(element);
}
else if(keep == priorityQueue.size()) {
priorityQueue.add(element); // size = keep +1 but
Object o = (Object)topN.toArray()[k-1];
topN.remove(o); // resized to keep
}
}
The fastest way is likely a simple array items = new Item[N]; and a revolving cursor int cursor = 0;. The cursor points to the insertion point of the next element.
To add a new element use the method
put(Item newItem) { items[cursor++] = newItem; if(cursor == N) cursor = 0; }
when accessing this structure you can make the last item added appear at index 0 via a small recalculation of the index, i.e.
get(int index) { return items[ cursor > index ? cursor-index-1 : cursor-index-1+N ]; }
(the -1 is because cursor always point at the next insertion point, i.e. cursor-1 is the last element added).
Summary: put(item) will add a new item. get(0) will get the last item added, get(1) will get the second last item, etc.
In case you need to take care of the case where n < N elements have been added you just need to check for null.
(TreeSets will likely be slower)
Your Question is answered here:
Size-limited queue that holds last N elements in Java
To summerize it:
No there is no data structure in the default java sdk, but Apache commons collections 4 has a CircularFifoQueue.

Get an element at a specific index from a NavigableSet

I have a NavigableSet and I would like to get its median object.
Being that it's a NavigableSet, I know it's sorted, and thus I know that the median of it is either the middle element, or the arithmetic middle of the two middle elements.
Therefore I would like to access the element at set.size() / 2, but the NavigableSet interface doesn't allow me to.
Is there an easy way to get the specific element without having to iterate through the set manually?
Yes set does not allow you to get an element from a particular index. But I think if you convert it to an array then you will be able to achieve what you need. I tried this sample code, see if it helps:
NavigableSet set = new TreeSet<Integer>();
set.add(new Integer(5));
set.add(new Integer(4));
set.add(new Integer(3));
set.add(new Integer(2));
set.add(new Integer(1));
Integer medianIndex = set.size()/2;
System.out.println(set.toArray()[medianIndex]);
Output: 3
Strings are ordered alphabetically, have a look at this small example:
Edit: Now it really does what you wanted.
public static void main(String[] args) {
NavigableSet<String> set = new TreeSet<String>();
set.add("gamma");
set.add("alpha");
set.add("beta");
System.out.println(Arrays.toString(set.toArray()));
int indexOfGamma = set.headSet("gamma").size();
System.out.println(indexOfGamma);
System.out.println(get(set, set.first(), indexOfGamma));
}
public static String get(NavigableSet<String> set, String e, int index) {
if (index == 0) {
return e;
}
return get(set, set.higher(e), --index);
}
This is the output:
[alpha, beta, gamma]
2
gamma
I didn't do any benchmarks with greater data-sets, but I guess it should perform quite decent. The higher() method should directly point to the next element in the tree.
I haven't been able to find any way other than iterating through the set "index" number of times. However, since we know the size of the set, we can speed that up to at least half the size by using both ascending and descending iteration:
public static <T> T getInNavigableSetByIndex(NavigableSet<T> set, int index) {
Objects.requireNonNull(set);
final int size = set.size();
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
final boolean descend = index >= size / 2;
final Iterator<T> itr = descend ? set.descendingIterator() : set.iterator();
final int stepCount = descend ? size - index : index + 1;
T object = null;
for (int i = 0; i < stepCount && itr.hasNext(); i++) {
object = itr.next();
}
return object;
}

Categories