Say, I have some class which holds an array of integers in it.
Integer[] numbers;
Also, I have some simple constructor which initializes my array:
public Program()
{
numbers = new Integer[11];
numbers[0] = null;
}
As you can see, I have an array of 11 elements.
The point is that I will never ever change the first one with index 0.
Is there a way to finalize the first element of my array, so it can't be changed?
Like with final variables.
No, you cannot do that with an array. In fact, inability to make array elements read-only is a major drawback of using arrays in situations when data could be modified externally.
The only approach to protect elements of your array is to encapsulate the array in a class that would check elements and indexes before performing modifications:
public class ArrayWithFixedFirst {
private final Integer[] numbers = new Integer[11];
public Integer get(int index) {
return numbers[index];
}
public void set(int index, Integer value) {
if (index == 0) throw new IllegalArgumentException();
numbers[index] = value;
}
}
I don't believe there is a way to specify that the first element of an array cannot be re-assigned.
I think your best bet would be to create a wrapper class for the array, and then ignore any attempts to re-assign the first element.
Through encapsulation, you can allow/disallow the array modification.
public void updateArray(int position,int value){
if(position > 0 && position < numbers.length){
numbers[position] = value;
}
}
You can not force an array to be unmodifiable. An alternative is using Collections.unmodifiableList. But the whole list will therefore be unmodifiable.
Intriguing question, but I'm going to have to say no. Java arrays will not allow you to finalize just one element. You could possibly get the same functionality by writing a custom wrapper, but that begs the question, why? I don't know what application you're going for, but I would recommend wrapping a ten element array and decrementing your index by one, and returning null for the zero'th index
I don't know why you'd do it, but something like this:
class NoFirstArray extends ArrayList {
public NoFirstArray(int size,Object initialValue) {
super(size);
super.set(0,initialValue);
}
public void set(Integer i, Object value) {
if(i == 0) throw RuntimeException();
super.set(i,value);
}
public void remove(int i) {
if(i == 0) throw RuntimeException();
super.remove(i);
}
}
Related
I am trying to remove an element from Array through a customized Iterator and I need to remove an element from my array. I know it's not very practical to use array, but I have some restrictions for some reasons.
Problem is I can't create an another array with the removed element and change the reference. Because I don't have the real reference in customized Iterator Class. I need the change the real reference. Let me explain this better in code:
public class Iterator<E>
{
private E[] buffer; // underlying buffer.
private int idx; // location of iterator in buffer.
private E last_element; // last element returned by this iterator.
public Iterator(E[] arr)
{
buffer = arr;
idx = 0;
}
/**
* Removes from the underlying collection the last element returned
* by this iterator.
*/
public void remove()
{
...
}
}
I can create a copy of buffer with removing the specified element and change the buffer reference to that. But I want this remove to effect the real array. So I
actually need to change the arr[].
Again I know this whole use of array is senseless while having the Collection hierarchy but I need a way to this in this manner. A reference to a reference is not a good terminology in this case, but I had an implementation for this in C++, and looking something for like a pointer to pointer.
Thank you in advance.
It is already the case in your example ...
Setting buffer to arr, allows to create a copy of the reference, to the same Array in the heap, containing the same references of all elements.
BUT the fact is you should not use array this way, if you want to remove element.
You simply should use a List of the same kind of element.
Change your implementation, to use List<E> instead of arrays, and you will be able to call the remove method on it, with effect on original passed instance of list.
If you want a "pointer of a pointer" I see two ways : the first one is to create an array with only one element or the second one would be to create your own wrapper class containing the element.
I will give an example of the first way:
public class Iterator<E>
{
private E[][] pointerToPointer;
private E[] buffer; // underlying buffer.
private int idx; // location of iterator in buffer.
private E last_element; // last element returned by this iterator.
public Iterator(E[][] pointerToPointer)
{
this.pointerToPointer = pointerToPointer;
buffer = pointerToPointer[0];
idx = 0;
}
/**
* Removes from the underlying collection the last element returned
* by this iterator.
*/
public void remove()
{
// create your new array (let's call it newArr)
...
buffer = newArr;
pointerToPointer[0] = buffer;
}
}
Then when you call your iterator, you have to create a singleton array:
Integer[] arr = ...
Integer[][] pointerToPointer = {arr};
Iterator<Integer> it = new Iterator<>(new Integer[][]{pointerToPointer});
//use your iterator, including remove() method
...
arr = pointerToPointer[0]; //this gets the modified array
Anyways, what is preventing you to add a method to your Iterator class that returns the field buffer?
Java is pass-by-value and not pass-by-reference, meaning; you are copying data, and letting the garbage collector (GC) taking care of the rest. So you don't have pointers, which you have in C++.
This is my idea, having one bad sideeffect - the array is fixed and allocated to the array parsed to the constructor (index is removed, but replaced with null):
public void remove(int index) {
#SuppressWarnings("unchecked")
E[] tmp = (E[])new Object[this.buffer.length]; // Can cause issues on some types
int x = 0; // Variable to track tmp's index counter
for(int i = 0; i < this.buffer.length; i++) {
if(i != index) {
x++;
tmp[x] = this.buffer[i];
}
}
this.buffer = tmp;
}
An interview question was to write this method to remove duplicate element in an array.
public static Array removeDuplicates(Array a) {
...
return type is java.lang.reflect.Array and parameter is also java.lang.reflect.Array type.
How would this method be called for any array?
Also not sure about my implementation:
public static Array removeDuplicates(Array a)
{
int end=Array.getLength(a)-1;
for(int i=0;i<=end-1;i++)
{
for(int j=i+1;j<=end;j++)
{
if(Array.get(a, i)==Array.get(a, j))
{
Array.set(a, j, Array.get(a, end));
end--;
j--;
}
}
}
Array b=(Array) Array.newInstance(a.getClass(), end+1);
for(int i=0;i<=end;i++)
Array.set(a, i, Array.get(a, i));
return b;
}
You may want to consider using a different data structure such as a hashmap to detect the duplicate (O(1)) instead of looping with nested for loops (O(n^2)). It should give you much better time complexity.
There are various problem with this code. Starting here:
if(Array.get(a, i)==Array.get(a, j))
Keep in mind that those get() calls return Object. So, when you pass in an array of strings, comparing with == simply will most likely result in wrong results (because many objects that are in fact equal still have different references --- so your check returns false all the time!)
So, the first thing to change: use equals() instead of == !
The other problem is:
end--;
Seriously: you never ever change the variable that controls your for loop.
Instead: have another counter, like
int numberOfOutgoingItems = end;
and then decrease that counter!
For your final question - check the javadoc; for example for get(). That reads get(Object array, int index)
So you should be able to do something like:
int a[] = ...;
Object oneValue = Array.get(a, 0);
for example.
Disclaimer. I have to admit: I don't know if the Array implementation is smart enough to automatically turn the elements of an int[] into an Integer object.
It could well be that you have to write code first to detect the exact type of array (if it is an array of int for example); to instead call getInt() instead of getObject().
Beyond that, some further reading how to use reflection/Array can be found here
I am trying to create a method that searches through the 'data' array to find the parameter 'elt'. If it exists, the method deletes it. I cannot figure out how to delete the string "elt". Below is what I have so far.
public class Bag<T> implements Iterable<T> {
private final int MAXLEN = 3;
private int size;
private T[] data; // array
public T remove(T elt) {
for (T word : data) {
if (word == "elt")
data = data.remove(word);
}
}
}
The error I get is "Cannot remove(T) on the array type T[].
Can someone tell me how I can properly remove the string "elt" from the array?
data is an array so you cannot remove it in the sense you are trying to do.
You have a few options:
Set the element to null
(1) and move the other elements down
Use a Collection (such as ArrayList) - then you can remove as you'd like
Option (3) would be the simplest. If you are required to use an array, (1) would look something like:
for (int i=0; i<data.length; i++) {
if ("elt".equals(data[i]) {
data[i] = null;
}
}
You can't "remove" a value from an array: you cannot change the number of elements in the array once it has been created.
You can, however, change the value of an element, e.g. setting it to null. In order to do this, you'd need the index of the element, so you can't use an enhanced for loop.
If you want a variable-size container, use a mutable List, e.g. ArrayList. You could then simply use list.remove("elt"), no explicit loop required.
Aside: use "elt".equals(word) instead of word == "elt".
So my program has a need of a type of circular ArrayList.
Only circular thing about it has to be the get(int index) method, this is the original:
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return
* #return the element at the specified position in this list
* #throws IndexOutOfBoundsException {#inheritDoc}
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
If index is -1 it should get the element with index ArrayList.size()-1 and if index is ArrayList.size(), it should get the element with index 0.
Simplest way of achieveing this which came to my mind is simply extending ArrayList from the java.util package and just overriding the get(int index) so it does not throw IndexOutOfBoundsException for the two indexes above, but change them to what I want. It would throw IndexOutOfBoundsException for any other index that is out of bounds.
However, since elementData(index) access a
private transient Object[] elementData;
I cannot make it work, because my class doesn't see it since it's private.
Also, I don't want to use any external libraries for this, simply because I think there are none that suit my needs, since I don't want a real circularArray, but only a part of it's functionality, rest of it being of the regular ArrayList.
So I have two questions:
How can I make this work? Is there a way to do it without copying the whole ArrayList class along with AbstractCollection, Collection and Iterable into my program? That seems like bad design even to me.
If I can somehow make it work, is there anything else I should watch for? If I make the changes described above, would that change the behaviour of the class only the way I want it to, or could there be any other undesired behaviour changes?
EDIT:
Thanks for the answer, here's what I've done:
import java.util.ArrayList;
public class CircularArrayList<E> extends ArrayList<E>
{
private static final long serialVersionUID = 1L;
public E get(int index)
{
if (index == -1)
{
index = size()-1;
}
else if (index == size())
{
index = 0;
}
return super.get(index);
}
}
It will wrap around the ArrayList, but only by one. I want it to throw an exception if I try to access any other element but the first and the last with anything except their regular ArrayList indexes.
You can extend the ArrayList class to change the functionality of the get method, without the need to access the elementData field:
public class CircularList<E> extends ArrayList<E> {
#Override
public E get(int index) {
return super.get(index % size());
}
}
The super.get method will still perform the range checks (but those will never fail).
You should be aware that doing this can give the ArrayList unstable indices. If the size of the list changes, then all indices outside of the normal range will change. For instance, if you have a list ['a','b','c','d','e'], then get(7) will return c. If you then do add('f'), then get(7) will suddenly return b, because get will now be working modulo 6 instead of modulo 5.
Can't you derive from ArrayList and override the the get(int index) method along those lines:
#Override
public E get(int index)
{
if(index < 0)
index = index + size();
return super.get(index);
}
What am I missing?
Note that this implementation would not fold arbitrary indices into your valid index range but only allow you to properly address your list from both the left and right sides (with positive and negative indices respectively, a bit like in Python).
What you described is basically getting the modulus of the index you want, and accessing that element in a list.
You could do the following with composition over inheritance:
Create a wrapper class for the interface List<T>, let's call it ListWrapper now
add a constructor accepting instance of List
let the List instance be protected, and name it to wrapped
Extend the wrapper class
Why do all this crap? This is implementation agnostic. One day, you might want to use this convenience on another implementation. Then you'll have to duplicate code, and hell begins. If you need a 3rd implementation too, and then add just one tiny bit of new functionality, you are doomed.
With a wrapper class in between:
you can have all classes implementing the List interface to have your own functinality
you'll be able to change the wrapper class in one place
you'll be able to add new functionality in one place.
Remember, we are writing programs that will have to be maintainable!
Wrapper class
public abstract class ListWrapper<T> implements List<T> {
protected final List<T> wrapped;
public ListWrapper(List<T> wrapped) {
this.wrapped = wrapped;
}
public T get(int index) {
return wrapped.get(index);
}
//omitting the other wrapper methods, for sake of brevity.
//Note: you still have to add them.
// Eclipse: Source menu, Generate Delegate methods does the trick nicely
}
Now the real new class
public class ModList<T> extends ListWrapper<T> {
public ModList(List<T> list) {
super(list);
}
#Override
public T get(int index) {
int listSize = wrapped.size();
int indexToGet = index % listSize;
//this might happen to be negative
indexToGet = (indexToGet < 0) ? indexToGet+listSize : indexToGet;
return wrapped.get(indexToGet);
}
}
BEWARE
this however is not safe for multithreaded environments!
be careful about all the instances of the original list - if you mutate that, the ModList instance will mutate too
The chosen answer doesn't handle the case where the index is a negative number with a very large magnitude and the size of the list is small i.e.
Size => 10
Index => -1000000
Here is an implementation that should handle all sizes and indexes
import java.util.ArrayList;
import java.util.Collection;
/**
* A list the loops round to the first element when {#link CircularList#get(int)} is called with an
* index that is greater than the max index of the list and vice versa.
*
* #author Stuart Clark
*/
public class CircularList<E> extends ArrayList<E> {
public CircularList() {
super();
}
public CircularList(int initialCapacity) {
super(initialCapacity);
}
public CircularList(Collection<? extends E> c) {
super(c);
}
#Override
public E get(int index) {
if (isEmpty()) {
throw new IndexOutOfBoundsException("The list is empty");
}
while (index < 0) {
index = size() + index;
}
return super.get(index % size());
}
}
Does anyone know this AbstractList extension : com.sun.appserv.management.util.misc.CircularList<T>. Take a look at it. It's GlassFish java.net community solution. It should be powerful because it's used in Thread Scheduling inside GlassFish Container.
As a sample, I am developing a simple MySortedSet in java which implements SortedSet interface. It is backed up with a simple array which is E[] array.
I have several questions regarding that:
This is the class: (I am not writing entire code, instead of related parts)
public class MySortedSet<E> implements SortedSet<E>, Iterator<E> {
private E[] array;
private Comparator<? super E> _comparator;
private int size = 0;
private int capacity;
#SuppressWarnings("unchecked")
public MySortedSet() {
this.capacity = 10;
this.array = (E[]) new Object[this.capacity];
// this.array = Array.newInstance(Class<E> var,int size);
// We have to get Class<E> from outside caller.
}
}
Since it accepts all sort of type from primitive to reference types etc. I am not really sure when removing an item, assigning null is a good way in place of the removed item. Since Java initializes primitive types with 0. So null only works for reference types.
Below is probably very bad design:
#Override
public boolean remove(Object o) {
int indexOfElement = this.find(o);
boolean removed = false;
if (indexOfElement != -1) {
this.array[indexOfElement] = null;
removed = true;
}
return removed;
}
Can someone tell me what the best way is to remove an element from an array?
Edit:
Honestly what I am thinking to remove an element from an simple array is like copy the entire array without the removed item into a whole new array but I am not sure how efficient it would be in terms of performance and etc.
It kinda depends on the context of how you want to use your array. For example, if you are going to be iterating over the array and using the contents of it for standard methods like Arrays.sort(), they might generate NullPointerExceptions if you have null values in your array.
If you really want to remove items from an array in a safe way, I'd suggest changing your array to an ArrayList like this...
ArrayList<Object> list = new ArrayList<Object>();
list.add(object);
list.remove(object);
As this will actually remove the item from the list completely - no nulls or anything will remain, and performing methods like length() will return a real value.
For instances when I have used an array, I set the value to null, and ensure that all iterations over the array check that value != null before I try to query it. After setting the nulls for the removed items, I usually loop over the array and manually sort all the nulls to the end of the array, and then do System.arraycopy() to resize the array. This will leave you with a new array of the correct size, with all items in it except for the removed ones. However, I suggest this only if you really must use an array, as it is slower and introduces much greater potential for errors and NullPointerExceptions.
Alternatively, if you're not worried about sort-order, you can simple move the last item in the array over the top of the item you want to remove, and keep a count of the real array size. For example...
Object[] array = new Object[20];
int realSize = 15; // real number of items in the array
public void remove(int arrayIndex){
array[arrayIndex] = array[realSize-1];
realSize--;
}
This method removes an item in the array by 'replacing' it with the item in the last position of the array - its very quick and pretty to implement, if you don't care about sort order.