I have a task to make my own Dynamic Array without using any ArrayLists or other pre-made classes for Arrays in java.
I get an Exception in thread "main" java.lang.NullPointerException error when I try to add my object (for example it's Integer).
Dinaminis<Integer> array = new Dinaminis<>();
array.ideti(5);
And my Dinaminis class looks like this:
public class Dinaminis<T> implements DArray<T>
{
private Object[] array;
private int kiek;
private Object[] temp;
public Dinaminis() {
array = new Object[10];
kiek = 0;
}
#Override
public void ideti(Object o) {
if (array.length == kiek) {
temp = new Object[kiek*2];
}
for (int i=1; i < kiek; i++){
temp[i] = array[i];
}
array = temp;
array[kiek] = o;
kiek++;
}
}
The thing is when I want to use "ideti" method, I want to check if the array is full, and if it's full it should create a double sized array. But I get an error even before my array is full.
Your ideti method is wrong. This should work:
public void ideti(Object o) {
if (array.length == kiek) {
temp = new Object[kiek*2];
// only copy old array to new array when old one is full
for (int i=0; i < kiek; i++){ // index starts at 0, not 1
temp[i] = array[i];
}
array = temp;
}
array[kiek] = o;
kiek++;
}
Your problem was that the loop that copies the old array to the new one was executed even when the original array wasn't full, in which case temp wasn't initialized, which led to NullPointerException.
I would suggest you store your array as your it's generic type T. I would pass in to the Class<T> to the Dinaminis constructor, then you can use Array.newInstance(). Also, I'd prefer to use System.arraycopy() and override toString() like
public class Dinaminis<T> implements DArray<T> {
private T[] array;
private int kiek;
private Class<T> cls;
public Dinaminis(Class<T> cls) {
this.cls = cls;
array = (T[]) Array.newInstance(cls, 10);
kiek = 0;
}
#Override
public void ideti(T o) {
if (kiek == array.length) {
T[] temp = (T[]) Array.newInstance(cls, array.length * 2);
System.arraycopy(array, 0, temp, 0, array.length);
array = temp;
}
array[kiek++] = o;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("len = %d [", array.length));
for (int i = 0; i < kiek; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(array[i]);
}
sb.append("]");
return sb.toString();
}
}
Then you could test it with something like
public static void main(String[] args) {
DArray<Integer> t = new Dinaminis<Integer>(Integer.class);
for (int i = 0; i < 11; i++) {
t.ideti(i);
}
System.out.println(t);
}
Output is
len = 20 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Obviously len was added to this output for pedagogical reasons, and in real code I probably wouldn't display it (except perhaps in a log message).
You need to initialize your temp array before using it.
You do initialize it inside of the if but not outside the if
temp = new Object[kiek*2];
so allocation of the double sized array should only happen when the size of the array is complete
if (array.length == kiek) //check if array size is reached
{
temp = new Object[kiek*2]; //allocate a double sized array
for (int i=1; i < kiek; i++) //copy elements - are you sure you don't want to start with i=0? You won't copy the first element if you start at 1
{
temp[i] = array[i];
}
array = temp;
}
Related
I have to reverse two arrays so that, they both have the same values but different references.
Here is my code so far.
But how to achieve that when both arrays are pointing to the same program arguments?
And why does String[] reference reverse the String[] values instead of reversing the program arguments?
For example. If the program arguments were 1 2 3 4 5:
String[] values = 5 4 3 2 1
String[] reference = 1 2 3 4 5
public static void main(String[] args) {
String[] values = changeValues(args);
System.out.println(Arrays.toString(values));
String[] reference = changeReference(args);
System.out.println(Arrays.toString(reference));
if (!testSameValues(values, reference)) {
System.out.println("Error: Values do not match !");
}
if (testSameReference(values, reference)) {
System.out.println("Error: References are the same !");
}
}
public static String[] changeValues(String[] x) {
for (int i = 0; i < x.length / 2; i++) {
String temp = x[i];
x[i] = x[(x.length - 1) - i];
x[(x.length - 1) - i] = temp;
}
return x;
}
public static String[] changeReference(String[] y) {
for (int i = 0; i < y.length / 2; i++) {
String temp = y[i];
y[i] = y[(y.length - 1) - i];
y[(y.length - 1) - i] = temp;
}
return y;
}
public static boolean testSameValues(String[] x, String[] y) {
if (x.equals(y)) {
return true;
} else
return false;
}
public static boolean testSameReference(String[] x, String[] y) {
if (x == y) {
return true;
} else
return false;
}
changeReference and changeValues methods do the same thing - reverse the array. That is why in the end you see the same input array.
To change the reference, you need to create a new array and populate it with the same elements from the original one.
EDIT: copying array into a new one
public static String[] changeReference(String[] y) {
String[] copy = new String[y.length];
for(int i = 0; i < y.length; i++) {
copy[i] = y[i]
}
return copy;
}
Your reverse method operates on the input array only and creates no new arrays. It's easy enough to write a method that will reverse a String[] and return a new array. Something like
private static String[] copyReverse(String[] arr) {
String[] ret = new String[arr.length];
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[arr.length - i - 1];
}
return ret;
}
Then you can call it successively. Like,
String[] values = copyReverse(args);
String[] reference = copyReverse(values);
I think you wanted two methods, one to copy an array and one to reverse an array. Let's make those methods generic, but to generically copy an array we need to pass the class as well. Something like,
private static <T> T[] copy(Class<T> cls, T[] arr) {
T[] ret = (T[]) Array.newInstance(cls, arr.length);
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[i];
}
return ret;
}
When reversing an array in place, I find it easier to read if I use two variables for positions in the array. Like,
private static <T> T[] reverse(T[] arr) {
for (int i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--) {
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return arr;
}
And to copyReverse generically,
private static <T> T[] copyReverse(Class<T> cls, T[] arr) {
T[] ret = (T[]) Array.newInstance(cls, arr.length);
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[arr.length - i - 1];
}
return ret;
}
To copy a String[] you could use either
String[] values = copy(String.class, args);
String[] reversed = copyReverse(String.class, args);
But if you use the inplace reverse it modifies the passed in array.
You can simply copy the reversed array and get two different references with the same content:
// original array
String[] arr1 = {"5", "7", "3", "2", "1"};
// reversed array
String[] arr2 = IntStream
// iterating in reverse order
.iterate(arr1.length, i -> i > 0, i -> i - 1)
// get an element by its index
.mapToObj(i -> arr1[i - 1])
.toArray(String[]::new);
// copy of the reversed array
String[] arr3 = Arrays.stream(arr2).toArray(String[]::new);
System.out.println(Arrays.toString(arr2)); // [1, 2, 3, 7, 5]
System.out.println(Arrays.toString(arr3)); // [1, 2, 3, 7, 5]
System.out.println(arr2 == arr3); // false
System.out.println(Arrays.equals(arr2, arr3)); // true
System.out.println(Arrays.compare(arr2, arr3)); // 0
See also: Swapping first array element with last, second with second last and so on
Clone the array:
String[] values = changeValues(args.clone());
String[] reference = changeReference(args.clone());
Note that since changeValues and changeReference do the same thing, you could just use changeValues for both or changeReference for both. The array's location in memory is based off of the location of the array passed in, not the name of the function.
I am working with implement arraylist. I want to write a method that takes the last element and inserts it at the front. So far I got it to take the last element and insert it in front, and shift everything over. But, I can't seem to be able to delete the last element that was inserted in front. for example: (1,2,5) to (5,1,2) but I got (5,1,2,5). I am missing something in my replaceArray() method, but I don't really know what. Thanks for the help.
Constructor for the class:
public KWArrayList() {
capacity = INITIAL_CAPACITY;
theData = (E[]) new Object[capacity];
}
public void replaceArray(int index, E anElement) {
for (int i = size; i > index; i--){
theData[i] = theData[i - 1];
}
theData[index] = anEntry;
size--;
for (int i = 0; i < theData.length; i++){
System.out.println(theData[i]);
}
}
I would use this simple way of rotating the array (I think the method should be called rotate instead of replaceAll, because it's actually rotation the array by one position).
Here's the method rotate():
#SuppressWarnings("unchecked")
public void rotate() {
Object[] temp = new Object[theData.length];
//copy each element, except the first, from theData into temp by shifting one position off to the right
for (int i = temp.length - 1; i > 0; i--) {
temp[i] = theData[i - 1];
}
//move the last element into the first position
temp[0] = theData[theData.length - 1];
//update theData
theData = (T[]) temp;
}
Complete testable example
public class MyArrayList<T> {
int INITIAL_CAPACITY = 10;
int capacity;
T[] theData;
#SuppressWarnings("unchecked")
public MyArrayList() {
capacity = INITIAL_CAPACITY;
theData = (T[]) new Object[capacity];
}
#SuppressWarnings("unchecked")
public MyArrayList(int capacity) {
this.capacity = capacity;
theData = (T[]) new Object[this.capacity];
}
#SuppressWarnings("unchecked")
public void rotate() {
Object[] temp = new Object[theData.length];
//copy each element, except the first, from theData into temp by shifting one position off to the right
// to the right
for (int i = temp.length - 1; i > 0; i--) {
temp[i] = theData[i - 1];
}
// move the last element into the first position
temp[0] = theData[theData.length - 1];
// update theData
theData = (T[]) temp;
}
/**
* For testing purposes only. It doesn't handle out of bounds values of
* index.
*/
private void insert(T t, int index) {
theData[index] = t;
}
public void print() {
for (T t : theData) {
System.out.print(t + ", ");
}
System.out.println();
}
#SafeVarargs
public static <E> MyArrayList<E> of(E... elements) {
MyArrayList<E> m = new MyArrayList<>(elements.length);
for (int i = 0; i < elements.length; i++) {
m.insert(elements[i], i);
}
return m;
}
}
Test the rotate() method:
public class TestMyArrayList {
public static void main(String[] args) {
MyArrayList<Integer> m = MyArrayList.of(1, 2, 3, 4, 5);
m.print();
m.rotate();
m.print();
}
}
It will print out:
1, 2, 3, 4, 5,
5, 1, 2, 3, 4,
import java.util.Arrays;
public class KWArrayList <E>{
private E[] data; /* your list */
private int nbElt = 0; /* nb of element in your list */
/* no need to store the capacity since data.length give it */
KWArrayList(int capacity){
data = (E[]) new Object[capacity]; /* create */
}
private void resize() {
E[] tmp = (E[]) new Object[2 * data.length]; /* if the number of element >= capacity you double the capacity and copy old elt */
data = Arrays.copyOf(data, 2 * data.length);
}
public void add(E elt) {
if(nbElt >= data.length) {
resize();
}
data[nbElt++] = elt; /* add an elt */
}
public void add(E ... elt) { /* add multiple elt */
for(E e : elt) {
add(e);
}
}
public E removeLast() { /* remove the last elt and return it */
if(nbElt == 0) {
throw new IllegalStateException("nothing to remove");
}
return data[--nbElt];
}
public void removeLastAndInsertFront() {
data[0] = removeLast();
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
if(nbElt == 0) {
return sb.append("]").toString();
}
for(int i = 0; i < nbElt; i++) {
sb.append(data[i]).append(", ");
}
sb.setLength(sb.length() - 2);
return sb.append("]").toString();
}
public static void main(String[] args) {
KWArrayList<Integer> data = new KWArrayList(1);
data.add(1, 2, 5);
System.out.println(data);
System.out.println("first delete");
data.removeLastAndInsertFront();
System.out.println(data);
System.out.println("second delete");
data.removeLastAndInsertFront();
System.out.println(data);
System.out.println("third delete");
data.removeLastAndInsertFront();
System.out.println(data);
}
}
public class MyArrayList extends ArrayList<Object>{
public void rotateRight(){
this.add(0, this.remove(this.size()-1));
}
public void rotateLeft(){
this.add(this.remove(0));
}
}
I've written this implementation. I'm assuming theData is of type int but you can change it to whatever. I also removed the parameters in the function since I don't use them.
First we copy the array into a temp variable.
Second, we save the first value in theData into another temp variable.
We then begin to shift starting from the beginning of theData until the second to last index.
Finally, we copy the first index saved from theData into first and assign it to the last index of the array.
Print
public void replaceArray() {
int [] temp = theData;
int last = theData[theData.length - 1];
for (int i = theData.length - 1; i > 0; i--){
temp[i] = theData[i - 1];
}
temp[0] = last;
for (int i = 0; i < theData.length; i++){
System.out.println(temp[i]);
}
}
use queue
if you waht your own, have a 2 ints of the positions of the begin and end of the list, while replaceArray just copy the element to position end; then end = (end+1) % capacity;begin = (begin +1) % capacity; (without removing - no need)
I am trying to deep copy a 4d int array as the solution of my algorithm. Unfortunately, when I call that solution at the end of my program, it is not the one that was supposed to be deepcopied. It is also neither the first nor the last created solution. I figure the problem must lie in deepCopy as cloning the same solution in a 1d array works fine.
I am trying to deepcopy w[][][][]:
public Object clone()
{
MySolution copy = (MySolution)super.clone();
copy.w = deepCopyOf(w);
copy.wtour = (int[])this.wtour.clone();
return copy;
} // end clone
#SuppressWarnings("unchecked")
public static <T> T[] deepCopyOf(T[] array) {
if (0 >= array.length) return array;
return (T[]) deepCopyOf(
array,
Array.newInstance(array[0].getClass(), array.length),
0);
}
private static Object deepCopyOf(Object array, Object copiedArray, int index) {
if (index >= Array.getLength(array)) return copiedArray;
Object element = Array.get(array, index);
if (element.getClass().isArray()) {
Array.set(copiedArray, index, deepCopyOf(
element,
Array.newInstance(
element.getClass().getComponentType(),
Array.getLength(element)),
0));
}
else {
Array.set(copiedArray, index, element);
}
return deepCopyOf(array, copiedArray, ++index);
}
I am using the openTS Tabu Search framework by Harder and the fact that the wtour array gets copied just fine shows me that there must be something wrong with the deepcopy method for w[][][][]
EDIT: novic3 assumed that I have to iterate over the different array levels. I tried doing the following which is a little bit different in its approach. Unfortunately, it still doesn't work.
public static int[][][][] deepCopy2(int[][][][] original) {
if (original == null) {
return null;
}
final int[][][][] result = new int[original.length][original[0].length][original.length+1][];
for (int i = 0; i < original.length; i++) {
for (int j = 0; j < original.length; j++) {
for (int q= 0; q <= original.length; q++) {
result[i][j][q] = Arrays.copyOf(original[i][j][q], original[i][j][q].length);
// For Java versions prior to Java 6 use the next:
//System.arraycopy(original[i], 0, result[i], 0, original[i].length);
}
}
}
return result;
}
This should work:
public int[] deepCopy(int[] w) {
int[] ans = new int[w.length];
for (int i = 0; i < w.length; i++) {
ans[i] = w[i];
}
return ans;
}
public int[][] deepCopy2(int[][] w) {
int[][] ans = new int[w.length][];
for (int i = 0; i < w.length; i++) {
ans[i] = deepCopy(w[i]);
}
return ans;
}
public int[][][] deepCopy3(int[][][] w) {
int[][][] ans = new int[w.length][][];
for (int i = 0; i < w.length; i++) {
ans[i] = deepCopy2(w[i]);
}
return ans;
}
public int[][][][] deepCopy4(int[][][][] w) {
int[][][][] ans = new int[w.length][][][];
for (int i = 0; i < w.length; i++) {
ans[i] = deepCopy3(w[i]);
}
return ans;
}
To use, call deepCopy4(w)
I want to return an array with the index's where the getElem() is equal or higher a certain value.
This is my function:
public static int []findIndex(BufferedImage image,int value)
{
DataBuffer b = image.getRaster().getDataBuffer();
int array[] = new int[600];
for(int i=0;i<76400;i++)
{
if(b.getElem(i)>=value)
array[i]=i;
}
return array;
}
but i have an error
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 27001
at arraytest.imageMan.findIndex(imageMan.java:139)
at arraytest.imageMan.main(imageMan.java:183)"
int array[] = new int[600];
The array you declare is of size 600.
for(int i=0;i<76400;i++)
Yet you attempt to reference the array at the 76400'th index.
Why doesn't this work?
Well, when you say new int[600], you are essentially saying, my array can store 600 things, and this means that it has 600 different "slots" to store values.
You access these values by their index, starting from 0.
array[0] // First item
array[599] // Last item.
Your error has occurred because you have exceeded 599.
How to fix this
Well, you can either make your array 76400 long, (which to me is suspicious), or you can change 76400 to array.length (or 600) in your for loop.
This is the solution i find..
I think that is the best..
public static int[] findIndex(BufferedImage image, int value) {
DataBuffer b = image.getRaster().getDataBuffer();
int array[] = new int[600];
int j = 0;
for (int i = 0; i < b.getSize(); i++) {
if (b.getElem(i) >= value) {
if (j < 600) {
array[j] = i;
j++;
}
}
}
return array;
}
That's because your loop from 0 to 76400, which much much greater than the size of your array.
public static int []findIndex(BufferedImage image,int value)
{
DataBuffer b = image.getRaster().getDataBuffer();
int array[] = new int[600];
for(int i=0;i<array.length;i++)
{
if(b.getElem(i)>=value)
array[i]=i;
}
return array;
}
This is my final function.
How should we choose a generic programming,i made some changes that made a focused precisely on that.
Use now have a list instead of a static array.
public static int[] findIndex(BufferedImage image, int value) {
DataBuffer b = image.getRaster().getDataBuffer();
ArrayList<Integer> a = new ArrayList<>(20);
int j = 0;
for (int i = 0; i < b.getSize(); i++) {
if (b.getElem(i) >= value) {
a.add(i);
j++;
}
}
int array[] = new int[a.size()];
for (int k = 0; k < a.size(); k++) {
array[k] = a.get(k);
}
return array;
}
I am trying to write my own version of a C++ STL vector<> I want it to make a dynamically growing and shrinking list...I want to have methods for push_back, push_front, pop_back, pop_front, remove, removeAt, clear, and size...I wrote all of these with little problem and am getting no build errors or warnings, when I try to instantiate the class Eclipse tells me that its looking for Dimensions after token...so it thinks any type I send in wants to be an array of that type, for instance...
DynaArray<int> Bob;
Here it wants the [] operator after the int.
Here is what my class presently looks like
public class DynaArray<T>
{
int Size = 0;
int CurrentCount = 0;
int LastSpot = 0;
T[] Array;
DynaArray(int _size)
{
Size = _size;
}
#SuppressWarnings("unchecked")
void push_back(T _element)
{
CurrentCount++;
if(CurrentCount > Size)
{
//make a new array for double the size;
if( Size == 0 )
{
Size = 2;
Array = (T[]) new Object[Size];
}
else
{
int OldSize = Size;
Size = Size*2;
T[] TempArray;
TempArray = (T[]) new Object[Size];
int i = 0;
for( ; i < OldSize; i++ )
{
//Copy over info from Array to TempArray
TempArray[i] = Array[i];
}
Array = TempArray;
}
}
//Now add the new element onto the array
Array[LastSpot] = _element;
LastSpot++;
}
#SuppressWarnings("unchecked")
void push_front(T _element)
{
CurrentCount++;
if( Size == 0)
{
Size = 2;
Array = (T[]) new Object[Size];
Array[0] = _element;
return;
}
else
{
int OldSize = Size;
Size = Size+1;
T[] TempArray;
TempArray = (T[]) new Object[Size];
int i = 1;
for( ; i < OldSize; i++ )
{
//Copy over info from Array to TempArray
TempArray[i] = Array[i-1];
Array = TempArray;
Array[0] = _element;
}
}
}
T pop_back()
{
if( CurrentCount <= 0)
return null;
else
{
return Array[CurrentCount-1];
}
}
T pop_front()
{
if( CurrentCount <= 0)
return null;
else
{
return Array[0];
}
}
int size()
{
return CurrentCount;
}
#SuppressWarnings("unchecked")
void clear()
{
Size = 0;
CurrentCount = 0;
LastSpot = 0;
Array = (T[]) new Object[2];
}
#SuppressWarnings("unchecked")
void removeAt(int index)
{
T[] TempArray = (T[]) new Object[Size];
int ArrayIndex = 0;
for( int i = 0; i < CurrentCount; i++)
{
if( i == index )
continue;
TempArray[ArrayIndex] = Array[i];
ArrayIndex++;
}
}
void remove(T _element)
{
for(int i = 0; i < CurrentCount; i++)
{
//look for the element
if( Array[i] == _element)
removeAt(i);
}
}
}
Thanks for any help provided or if my code somehow helped you are welcome
int is a primitive, and as such cannot be used with Java generics. The reason for this is to maintain the bytecode's backwards compatibility (which was important when generics were first introduced). You must use an Integer instead.
N.B. unless you're doing this as an academic exercise, you can/should just use a List<T> instead of your custom-implemented class.
Alternatively: use Trove.
You cannot use Java primitives as a generic type because they are not instances of Object. The reason why int[] works is because a Java array is an object. Use the boxed Integer instead.