This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 4 years ago.
I am running into conversion errors with Generics. I can provide the full code if needed but I feel like I am missing something really simple. I am attempting to use a method inside of my class to add all elements of input list to current list, but I am getting conversion errors for E.
Can somebody please point me in the right direction as to what I need to be doing? - I am not new to programming, but Java isn't my first language.
public class ArrayList<E> implements List<E> {
// instance variables
/** Default array capacity. */
public static final int CAPACITY=16; // default array capacity
private E[] data; // generic array used for storage
private int size = 0; // current number of elements
public ArrayList() { this(CAPACITY); } // constructs list with default capacity
#SuppressWarnings({"unchecked"})
public ArrayList(int capacity) { // constructs list with given capacity
data = (E[]) new Object[capacity]; // safe cast; compiler may give warning
}
// public methods
public int size() { return size; }
public boolean isEmpty() { return size == 0; }
public E get(int i) throws IndexOutOfBoundsException {
checkIndex(i, size);
return data[i];
}
public void add(int i, E e) throws IndexOutOfBoundsException {
checkIndex(i, size + 1);
if (size == data.length) // not enough capacity
resize(2 * data.length); // so double the current capacity
for (int k=size-1; k >= i; k--) // start by shifting rightmost
data[k+1] = data[k];
data[i] = e; // ready to place the new element
//print(data[i].getClass());//STRING BASED ON CURRENT TEST CODE
size++;
}
//-------ERROR CODE
public void addAll(ArrayList l){
//Adds all elements in l to the end of this list, in the order that they are in l.
//Input: An ArrayList l.
//Output: None
//Postcondition: All elements in the list l have been added to this list.
//add(int i, E e)
//l IS ALSO AN ARRAY LIST SO SAME METHODS/VARIABLES APPLY...JUST REFERENCE l'S VERSION
//add(0,"hi");//ERROR NOT E
int foundSize = l.size();
//print(foundSize);
print("SIZE:"+size);
print("LENGTH:"+data.length);//TOTAL
for (int i=0; i < foundSize; i++){
//print(data[i]);
this.add(size(), l.get(i));//INCOMPATIBLE TYPES
}
}
//-------ERROR CODE
You are passing a raw ArrayList to your addAll method.
Change
public void addAll(ArrayList l)
to
public void addAll(ArrayList<E> l)
Related
I want to shift the elements in the array in a queue style.
I did this code:
public class Queue {
private int[] elements;
private int size;
public static final int DefCap = 8;
public Queue() {
this(DefCap);
}
public Queue(int capacity) {
elements = new int[capacity];
}
public int[] enqueue(int v) {
if (size >= elements.length) {
int[] a = new int[elements.length * 2];
System.arraycopy(elements, 0, a, 0, elements.length);
elements = a;
}
elements[size++] = v;
return elements;
}
public int dequeue() {
return elements[--size];
}
public boolean empty() {
return size == 0;
}
public int getSize() {
return size;
}
}
How can I shift the numbers in the array where the next number added pushes the last one?
because all it does now is removes the last one added (Stacking).
First, remember that it doesn't matter at all how you add or retrieve the elements as long as it appears that the operation reflects that of a queue (i.e. FIFO). The internals of your implementation are of no concern to the user(s). The easiest method (imo) is to add them normally to the end and "remove" them from the beginning.
When you add the new element, do it like you are already doing it.
When you remove the first element, do it virtually by using an index.
int nextIdx = 0; // initialize start of queue
...
...
public int next() {
if (nextIdx < elements.length) {
return elements[nextIdx--];
}
// indicate an error by throwing an exception
}
At some point you are going to want to reclaim the "non-existent" elements at the beginning of the queue and then reset nextIdx. You can do this when you need to resize the array. You can use System.arraycopy and make use of both the value of nextIdx and the new desired new size to resize the array and copy the remaining elements.
Note: In your enqueue method I'm not certain why you want to return the entire element array when you add an element. I would expect something like returning the element just added, a boolean indicating success, or not return anything.
help here will be greatly appreciated. I'm pretty stuck. What I have to do is I have to use the selection sort algorithm to sort an arraylist, but there are multiple indexes in each object in the arraylist. This has to be done in java.
For example:
public class a {
private int number;
private String letter;
public a(int n, String l)
{
number = n;
letter = l;
}
}
public class SortingArrays {
private ArrayList<a> myarray;
private Comparator<a> sortByNumber;
private Comparator<a> sortByLetter;
public FootballPlayerData() {
myarray = new ArrayList<a>();
getmyarray().add(new a(2, "A"));
getmyarray().add(new a(7, "J"));
//COMPARATORs//
sortByNumber = new Comparator<a>() {
#Override
public int compare(a o1, a o2)
{
if (o1.number < (o2.number)) {
return -1;
}
if (o1.number == (o2.number)) {
return 0;
}
return 1;
}
};
sortByLetter = new Comparator<a>() {
#Override
public int compare(a o1, a o2)
{
return o1.letter.compareTo(o2.letter);
}
};
public void selectionSortbyNumber
{
???
}
public void selectionSortbyLetter
{
???
}
}
So how do I create a selection sort in java (has to be selection sort) that sorts the arraylist by different elements within the objects? I already have the comparator part down, but I don't know how to incorporate that with selection sort.
A Comparator implementation is usually used to compare two elements with one another, returning -1 (or any negative number) if the first element is less than the second, 0 if they are equal, and 1 (or any positive number) if the first element is greater than the second. This can be used to compare two elements to see if one is greater, less than, or equal to the other.
In the context of selection sort, you can use a supplied comparator to determine which value in the unsorted portion of the list is the minimum. The general algorithm for selection sort is as follows:
for i from 0 to array.length:
current_minimum_index = i
for j from i + 1 to array.length:
if array at j is less than array at current_minimum_index:
current_minimum_index = j
swap array at current_minimum_index with array at i
The if array at j is less than array at current_minimum_index can be implemented using Comparator. For example, given a supplied ArrayList called array, the call to the Comparator object named comparator would be:
if (comparator.compare(array.get(j), array.get(current_minimum_index))) < 0)
I do not want to provide you with the complete answer, as that would not help you learn selection sorting, but the method signature for your sorting would resemble the following:
public <T> void selectionSort(ArrayList<T> array, Comparator<T> comparator) {
// for i from 0 to array.size():
// currentMinIndex = i
// for j from i + 1 to array.size():
if (comparator.compare(array.get(j), array.get(currentMinIndex))) < 0) {
// currentMinIndex = j
}
// swap array at currentMinIndex with array at i
}
Your call to this method would then look like one of the following:
selectionSort(myarray, sortByNumber);
selectionSort(myarray, sortByLetter);
Source from https://en.wikipedia.org/wiki/Selection_sort:
/* a[0] to a[n-1] is the array to sort */
int i,j;
int n;
/* advance the position through the entire array */
/* (could do j < n-1 because single element is also min element) */
int iMin;
for (j = 0; j < n-1; j++) {
/* find the min element in the unsorted a[j .. n-1] */
/* assume the min is the first element */
iMin = j;
/* test against elements after j to find the smallest */
for (i = j+1; i < n; i++) {
/* if this element is less, then it is the new minimum */
if (a[i] < a[iMin]) {
/* found new minimum; remember its index */
iMin = i;
}
}
}
if (iMin != j) {
swap(a[j], a[iMin]);
}
The method swap() just switch the values in the array.
Your job will be to swap the array with list. :P But that's not so hard because you can access the list value by index get(int index) method.
i was wondering how can i reorder enum so that all goats are at the beginning and all sheep are at the end of the array. Right now it actually does the trick but until the array size > 100.. The reordering speed also matters so api methods are bit too slow. Any suggestions?
public class Sheep {
enum Animal {sheep, goat};
public static void main (String[] param) {
reorder(Animal.values());
}
public static void reorder (Animal[] animals) {
int l, r, i, j;
i = l = 0; //left most element
r = animals.length - 1;//right most element
int mid = (r+l)/2; // middle element of the array
for(i=0; i < animals.length;i++)
{
if(i < mid)
{
animals[i] = animals[l+1];
System.out.println(animals[r]);
} else if(i >= mid )
{
animals[i] = animals[r-1];
System.out.println(animals[r]);
}
}
}
}
Since an enum implements Comparable, you can simply sort and then reverse the array:
public static void reorder(Animal[] animals) {
Arrays.sort(animals);
for (int i = 0, j = animals.length - 1; i < j; ++i, --j) {
Animal tmp = animals[i];
animals[i] = animals[j];
animals[j] = tmp;
}
}
You might also be able to do it with:
List<Animal> list = Arrays.asList(animals);
Collections.sort(list);
Collections.reverse(list);
This basically does the same thing with API calls with the (very slight) overhead of wrapping the array in a List object. You can even do this:
Arrays.sort(animals, Collections.reverseOrder());
(Thanks to Bhesh Gurung for the idea.)
EDIT: If you have to deal with exactly two values, you can do much better by simply scanning from both ends, swapping as you find two elements out of order:
public static void reorder(Animal[] animals) {
int first = 0;
int last = animals.length - 1;
while (first < last) {
/*
* The unsorted elements are in positions first..last (inclusive).
* Everything before first is the higher animal; everything after
* last is the lower animal.
*/
while (animals[first].ordinal() == 1 && first < last) {
++first;
}
while (animals[last].ordinal() == 0 && first < last) {
--last;
}
if (first < last) {
/*
* At this point, the sort conditions still hold and also we know
* that the animals at first and last are both out of order
*/
Animal temp = animals[first];
animals[first] = animals[last];
animals[last] = temp;
++first;
--last;
}
}
}
However, if all you need to do is generate the right output (and not actually sort the array), then the approach suggested by #ajb in a comment is the best: just count how many sheep and goats there are and print the corresponding values that many times.
If you want to have maximum performance for such a special case you may simply count the number of one of the two possible values and overwrite the array accordingly to get the result that sorting would create:
public static void reorder (Animal[] animals) {
assert Animal.values().length==2;
int numGoat=0;
for(Animal a:animals) if(a==Animal.goat) numGoat++;
Arrays.fill(animals, 0, numGoat, Animal.goat);
Arrays.fill(animals, numGoat, animals.length, Animal.sheep);
}
You can see it as a modified version of counting sort.
I'm trying to generate arrays and calculate there values depending on some function. and I want to save each generated array into array List PQ.
the important methods are :
init: to initiate a series of arrays
calculate: is to calculate array measurement or value in this method I want to check if this array is already have been calculated by searching in PQ array which will have all previous calculated array.
badly, after each for stage for (j=0;j<s;j++) the sol[] object some how changed in the array list and the array list never updated with new values.
it is like there is object link between PQ.add(sol) and the calculate(solution);
how to remove this link i.e. pass-by-reference and convert it to pass-by-value so I can add new arrays to PQ Arraylist.
in another way how to pass array as value instead of reference ?
this is my code:
ArrayList previous_values=new ArrayList();
ArrayList PQ=new ArrayList();
void init(int index)
{
int j;
for (j=0;j<s;j++)
{
r = j+1;
array [index][j]=r*index;
solution[j]=array[index][j];
}
f[index]=calculate(solution);}
double calculate(int sol[])
{
double r;
r=search_Previous(sol);
if(r==-1) {
PQ.add(sol);
r=sol[0]*5;
previous_value.add(r);
}
}
public double search_Previous(int[] arr)
{
double d=-1;
for(int i=0;i<PQ.size();i++)
{
if(equal_arr(arr,(int[])(PQ.get(i))))
{
return (double)previous_value.get(i) ;
}
}
return d;
}
public static boolean equal_arr(int[] list1, int[] list2) {
// Now test if every element is the same
for (int i = 0; i < list1.length; i++) {
if (list1[i] != list2[i])
return false; // If one is wrong then they all are wrong.
}
// If all these tests worked, then they are identical.
return true;
}
thanks
Hope i get you question
.. how to pass array as value instead of reference ?
You need to copy the array. Use System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
double calculate(int sol[])
{
double r;
r=search_Previous_f(sol);
if(r==-1) {
PQ.add(sol);
}
btw you didn't closed the if statement
Add a method void removeFirst(int newVal) to the IntegerList class that removes the first occurrence of a value from the list. If the value does not appear in the list, it should do nothing (but it's not an error). Removing an item should not change the size of the array, but note that the array values do need to remain contiguous, so when you remove a value you will have to shift everything after it down to fill up its space. Also remember to decrement the variable that keeps track of the number of elements.
Please help, I have tried all of the other solutions listed on this site regarding "removing an element from an array" and none have worked.
This method supports the same functionality as Collection.remove() which is how an ArrayList removes the first matching element.
public boolean remove(int n) {
for (int i = 0; i < size; i++) {
if (array[i] != n) continue;
size--;
System.arraycopy(array, i + 1, array, i, size - i);
return true;
}
return false;
}
Rather than write this code yourself, I suggest you look at Trove4J's TIntArrayList which is a wrapper for int[] You can also read the code for ArrayList to see how it is written.
You could do this:
int count; //No of elements in the array
for(i=0;i<count;i++)
{
if(Array[i]==element )
{
swap(Array,i,count);
if(count)
--count;
break;
}
}
int swap(int Array[],int i,int count)
{
int j;
for(j=i;j<=count-i;j++)
a[i]=a[i+1];
}
This is not the Full Implementation.You have to create a class and do this.
Using the method below
public static <TypeOfObject> TypeOfObject[] removeFirst(TypeOfObject[] array, TypeOfObject valueToRemove) {
TypeOfObject[] result = Arrays.copyOf(array, array.length - 1);
List<TypeOfObject> tempList = new ArrayList<>();
tempList.addAll(Arrays.asList(array));
tempList.remove(valueToRemove);
return tempList.toArray(result);
}
You can remove the first element of any array by calling the method as demonstrated in the below JUnit test.
#Test
public void removeFirstTest() {
// Given
Integer valToRemove = 5;
Integer[] input = {1,2,3,valToRemove,4,valToRemove,6,7,8,9};
Integer[] expected = {1,2,3,4,valToRemove,6,7,8,9};
// When
Integer[] actual = removeFirst(input, valToRemove);
// Then
Assert.assertArrayEquals(expected, actual);
}