How to add an element at the end of an array? - java

I want to know how to add or append a new element to the end of an array. Is any simple way to add the element at the end? I know how to use a StringBuffer but I don't know how to use it to add an element in an array. I prefer it without an ArrayList or list. I wonder if the StringBuffer will work on integers.

You can not add an element to an array, since arrays, in Java, are fixed-length. However, you could build a new array from the existing one using Arrays.copyOf(array, size) :
public static void main(String[] args) {
int[] array = new int[] {1, 2, 3};
System.out.println(Arrays.toString(array));
array = Arrays.copyOf(array, array.length + 1); //create new array from old array and allocate one more element
array[array.length - 1] = 4;
System.out.println(Arrays.toString(array));
}
I would still recommend to drop working with an array and use a List.

Arrays in Java have a fixed length that cannot be changed. So Java provides classes that allow you to maintain lists of variable length.
Generally, there is the List<T> interface, which represents a list of instances of the class T. The easiest and most widely used implementation is the ArrayList. Here is an example:
List<String> words = new ArrayList<String>();
words.add("Hello");
words.add("World");
words.add("!");
List.add() simply appends an element to the list and you can get the size of a list using List.size().

To clarify the terminology right: arrays are fixed length structures (and the length of an existing cannot be altered) the expression add at the end is meaningless (by itself).
What you can do is create a new array one element larger and fill in the new element in the last slot:
public static int[] append(int[] array, int value) {
int[] result = Arrays.copyOf(array, array.length + 1);
result[result.length - 1] = value;
return result;
}
This quickly gets inefficient, as each time append is called a new array is created and the old array contents is copied over.
One way to drastically reduce the overhead is to create a larger array and keep track of up to which index it is actually filled. Adding an element becomes as simple a filling the next index and incrementing the index. If the array fills up completely, a new array is created with more free space.
And guess what ArrayList does: exactly that. So when a dynamically sized array is needed, ArrayList is a good choice. Don't reinvent the wheel.

The OP says, for unknown reasons, "I prefer it without an arraylist or list."
If the type you are referring to is a primitive (you mention integers, but you don't say if you mean int or Integer), then you can use one of the NIO Buffer classes like java.nio.IntBuffer. These act a lot like StringBuffer does - they act as buffers for a list of the primitive type (buffers exist for all the primitives but not for Objects), and you can wrap a buffer around an array and/or extract an array from a buffer.
Note that the javadocs say, "The capacity of a buffer is never negative and never changes." It's still just a wrapper around an array, but one that's nicer to work with. The only way to effectively expand a buffer is to allocate() a larger one and use put() to dump the old buffer into the new one.
If it's not a primitive, you should probably just use List, or come up with a compelling reason why you can't or won't, and maybe somebody will help you work around it.

As many others pointed out if you are trying to add a new element at the end of list then something like, array[array.length-1]=x; should do. But this will replace the existing element.
For something like continuous addition to the array. You can keep track of the index and go on adding elements till you reach end and have the function that does the addition return you the next index, which in turn will tell you how many more elements can fit in the array.
Of course in both the cases the size of array will be predefined. Vector can be your other option since you do not want arraylist, which will allow you all the same features and functions and additionally will take care of incrementing the size.
Coming to the part where you want StringBuffer to array. I believe what you are looking for is the getChars(int srcBegin, int srcEnd,char[] dst,int dstBegin) method. Look into it that might solve your doubts. Again I would like to point out that after managing to get an array out of it, you can still only replace the last existing element(character in this case).

one-liner with streams
Stream.concat(Arrays.stream( array ), Stream.of( newElement )).toArray();

Related

Java array vs Array

It's been a while since I took a proper course on Java and I'm hoping someone can confirm/correct my understanding.
Consider the variables int[] arr and ArrayList arrLi:
arr has pointers directly to each component. arr[3] goes directly to the fourth element whereas arrLi.get(3) would have to traverse through the first three elements to get to the fourth.
Reassigning a component, such as a[3] = 0, does not rewrite the entire array.
Each time you want to add an element to arr, you would need to rewrite the entire array. For example, if there are 100 elements in arr, you have to make a new array with size 101 and copy all the elements from arr then add the new one. If you later decide to add yet another element, you'd have to go through the whole process again to add the 102-nd element.
arrLi adds (to end, front, or middle) and removes elements very efficiently because all it does is add/remove nodes and adjust the links.
ArrayList is a resizable array implementation of the List interface. Therefore fetching an element does not require traversing the previous elements.
Rewriting a value does not require rewriting the entire array in either case.
Yes, an array does need to be recreated if you need more space.
While it is called a list, ArrayList internally behaves much more like an array. ArrayList sometimes needs to be resized, meaning the underlying array needs to be recreated. However, this happens infrequently enough to not affect the average performance of an ArrayList over an array by much.
Please refer to https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html for more information

Copy array without redundancy

I have two arrays in my program. One is full(with redundant items in it). I want to copy all the items to the second empty array without redundancy. The only problem I have is "how to declare size of the second array?" Because Iam not sure how many are the redundant items in the first array.
I would use Set for this, that will remove duplicates from your array and you convert then back to array or another collection of you need that.
Set<Item> withoutDups = new HashSet<Item>(Arrays.asList(yourArray));
//now you have it without duplicates and do whatevet you want with it:-)
Item[] arrayWithoutDups = new Item[withoutDups.size()];
withoutDups.toArray(arrayWithoutDups); // fill the array
Convert string array to list. Use a LinkedHashSet to eliminate duplicates. The LinkedHashSet maintains insertion order along with uniqueness.
Edit: I have removed the List as it is redundant.
String[] words = {"ace", "ace","boom", "crew", "dog", "eon"};
Set<String> hs = new LinkedHashSet<String>(Arrays.asList(words));
String[] mywords=hs.toArray(new String[hs.size()]);
for(int i=0;i<mywords.length;i++)
{
System.out.println("..."+mywords[i]);
}
Arrays are of fixed size. You should use ArrayList in this case.
However, if you have to use an array then you should allocate the size of 2nd array equal to the size of 1st array because it may contain no redundant elements at all.
Use ArrayList which size can be smaller than original array, then create array from it, if needed.
So what's the problem ?
Loop through values in source array, find number of redundant items. Then allocate second array and in next loop copy values.
Complexity of this approach is 2n=O(n)
Since you don't know which item are redundant you need to loop over your array. I suggest that you use temporary List uniqueItemsList to add the items during your loop.
The list will grow as needed.
Then you can get a array with code like this (replace String with your type) :
String uniqueItems[] = new String[uniqueItemsList.size()];
uniqueItems = uniqueItemsList.toArray(uniqueItems);

how to make an array in java without length?

I am making an algorithm to save a path of zeroes between 0 1 array
the length of the path will be variable and so i need an array without predefined length
You cannot use array without specifying its length. Consider using ArrayList instead.
You can use an ArrayList which can be between 0 and around 2 billion in lengths.
If you use using a values or 0 and 1, a BitSet may be more efficient.
You can use:
ArrayList<Integer> al = new ArrayList<Integer>();
Note if you wanted to sort this array (for example in ascending order) - you would NOT use
Arrays.Sort(al);
You WOULD use:
Collections.Sort(al);
Use ArrayList instead. An ordinary array cannot be resized so easily - you would have to create a new one of a bigger size and copy the old one into it - I would not recommend this.
ArrayList al = new ArrayList();
al.add(0);
al.add(1);
You can always create array dynamically, e.g. new int[n] where n contains the array length at this moment (not pre-defined at compile time).
But array size cannot be changed. If you need this you should use List instead:
List<Integer> list = new ArrayList<Integer>();
Now you can add and remove elements when you need and the list size will be changed dynamically: you do not have to care about it:
list.add(123);
list.remove(456);
Use ArrayList for a dynamic size.
you can use ArrayList<Boolean> or ArrayList<Integer> and just use the add method. Then utilise the utility methods to get an array out when you are finished constructing the path.
String myArray[] = new Sting[YourVariable];
If speed is a real issue... and you need a dynamically changing array, you could try the following:
// this only works for increasing array-size
int[] tmp = new int[new_bigger_size]; // create a new array
System.arraycopy(array, 0, tmp, 0, array.length); // copy the data
int nextPosition = array.length
array = tmp; // assign the reference
// from position array.length (nextPosition), the new elements can be copied,
// for example:
array[nextPosition] = 120;
....
NOTE! This is very C-ish and not ideal. It is also more difficult to maintain uses more memory during the resizing and is regarded as bad form. Only try this as a last resort and if an ArrayList is really not working for you in terms of speed.
Having said that, does someone have an idea of how much slower (if any) an ArrayList will be?

Starting Size for an ArrayList

I want to use an ArrayList (or some other collection) like how I would use a standard array.
Specifically, I want it to start with an intial size (say, SIZE), and be able to set elements explicitly right off the bat,
e.g.
array[4] = "stuff";
could be written
array.set(4, "stuff");
However, the following code throws an IndexOutOfBoundsException:
ArrayList<Object> array = new ArrayList<Object>(SIZE);
array.set(4, "stuff"); //wah wahhh
I know there are a couple of ways to do this, but I was wondering if there was one that people like, or perhaps a better collection to use. Currently, I'm using code like the following:
ArrayList<Object> array = new ArrayList<Object>(SIZE);
for(int i = 0; i < SIZE; i++) {
array.add(null);
}
array.set(4, "stuff"); //hooray...
The only reason I even ask is because I am doing this in a loop that could potentially run a bunch of times (tens of thousands). Given that the ArrayList resizing behavior is "not specified," I'd rather it not waste any time resizing itself, or memory on extra, unused spots in the Array that backs it. This may be a moot point, though, since I will be filling the array (almost always every cell in the array) entirely with calls to array.set(), and will never exceed the capacity?
I'd rather just use a normal array, but my specs are requiring me to use a Collection.
The initial capacity means how big the array is. It does not mean there are elements there. So size != capacity.
In fact, you can use an array, and then use Arrays.asList(array) to get a collection.
I recomend a HashMap
HashMap hash = new HasMap();
hash.put(4,"Hi");
Considering that your main point is memory. Then you could manually do what the Java arraylist do, but it doesn't allow you to resize as much you want. So you can do the following:
1) Create a vector.
2) If the vector is full, create a vector with the old vector size + as much you want.
3) Copy all items from the old vector to your new vector.
This way, you will not waste memory.
Or you can implement a List (not vector) struct. I think Java already has one.
Yes, hashmap would be a great ideia.
Other way, you could just start the array with a big capacity for you purpose.

Using variable name as array index

I have few files which I put in array.
I shuffle the files so that it can be displayed in random order.
How to know that array index 0 is actually image1.txt or image2.txt or image3.txt?
Thanks in advance.
String[] a = {"image1.txt","image2.txt","image3.txt"};
List<String> files = Arrays.asList(a);
Collections.shuffle(files);
I'm not sure what you are trying to do.
To access the first element of the shuffled list, use files.get(0).
If you want to know where each element is gone, I suggest you take another approach to it. Create a list of integers from 0 to a.length() - 1, inclusive and shuffle that list. Then manually permute the array a to a new collection.
INCORRECT - see explanation
Note: Arrays.asList() will create a NEW list with the contents of the passed array. The original array will not be modified at all when you use Collections.shuffle().
Explanation
Peter has correctly pointed our that Arrays.asList() does NOT make a copy. The returned list is "write-through" back to the original array. Shuffling the list will shuffle the contents of the original array. Also worth noting that the list is immutable (new elements cannot be added) but typically I find that the use of Arrays.asList() involves immutable lists anyway.
files.get(0); // get the first elements in shuffled list, random
// as greg said
int index = files.indexOf(a[0]); // find out where "image1.txt" is in the list
files.get(index); // get "image1.txt" back from the list

Categories