I have a method to add a collection of generic elements to my array but do not know how to implement this. I have symbolised the line of code that I have been having trouble with as COLLECTION. I do not know what to write in place of this. My array is a circular ring array.
import java.util.Collection;
import java.util.Iterator;
public class CircularArrayRing<E> implements Ring<E> {
public E[] elements; //array of E
private int capacity;
private int writePos = 0;
private int available = 0;
public CircularArrayRing(int size) { //circular array constructor
capacity = size;
}
public boolean add(E e) {
if(available < capacity){
if(writePos >= capacity){
writePos = 0;
}
elements[writePos] = e; //add element e
writePos++;
available--;
return true;
}
return false;
}
public boolean addAll(Collection<? extends E> c) {
if(available < capacity){
if(writePos >= capacity){
writePos = 0;
}
elements[writePos] = COLLECTION; //how do add a collection of elements?
writePos++;
available++;
return true;
}
return false;
}
}
What about iterating and triggering add() one by one?
public boolean addAll(Collection<? extends E> c){
for(E e : c){
add(e);
}
}
The functional way.
c.forEach(this::add);
You can find out some ideas here:
https://github.com/bekkopen/Continuous-Delivery-example/blob/master/webapp/src/main/java/no/bekk/bekkopen/cde/jetty/config/CollectionBuilder.java#L10
public static <T> Set<T> newSet(final T... elements) {
return new HashSet<T>(Arrays.asList(elements));
}
public static <T> List<T> newList(final T... elements) {
return new ArrayList<T>(Arrays.asList(elements));
}
Here is some examples:
public void testCollectionAdd() {
if (!isAddSupported()) return;
Object[] elements = getFullElements();
for (int i = 0; i < elements.length; i++) {
resetEmpty();
boolean r = collection.add(elements[i]);
confirmed.add(elements[i]);
verify();
assertTrue("Empty collection changed after add", r);
assertTrue("Collection size is 1 after first add",
collection.size() == 1);
}
resetEmpty();
int size = 0;
for (int i = 0; i < elements.length; i++) {
boolean r = collection.add(elements[i]);
confirmed.add(elements[i]);
verify();
if (r) size++;
assertEquals("Collection size should grow after add",
size, collection.size());
assertTrue("Collection should contain added element",
collection.contains(elements[i]));
}
}
Full code here:
http://code.openhub.net/file?fid=WKY7Buaz9RI_B0BqM_HKnkm6lqY&cid=9RkvURzZ1wM&s=How%20to%20Add%20a%20collection%20of%20elements%20to%20my%20array%3F&pp=0&fl=Java&ff=1&projSelected=false&filterChecked,=true&mp,=1&filterChecked=true&mp=1&ml=1&me=1&md=1#L79
Related
I have troubles implementing an Iterator for my TupleHashSet class.
The hashArr attribute stores the Hashsets for my Tuple (Pair) objects. The insert method inserts the Tuples according to the calculated HashCode.
The problem is that my iterator doesn't iterate through the entire HashArr if I insert something with the method.
My teacher told me a tip that my approach is wrong since the HashSet value aren't interested in order. However, I'm not sure what he means with that.
TupleSet
public class TupleSet<T, S> implements Iterable<Tuple<T, S>> {
private final Tuple<T, S>[] hashArr;
public static final int SS = 999;
public TupleHashSet() {
hashArr = new Tuple[SS];
}
#Override
public java.util.Iterator<Tuple<T, S>> iterator() {
return new Iterator(hashArr);
}
class Iterator implements java.util.Iterator<Tuple<T, S>> {
private Tuple<T, S>[] array;
private int index = 0;
Iterator(Tuple<T, S>[] t) {
this.array = t;
}
#Override
public boolean hasNext() {
for (int i = index; i < SIZE; ++i) {
if (array[i] != null) {
return true;
}
}
return false;
}
#Override
public Tuple<T, S> next() {
for (int i = index; i < SIZE; ++i) {
if (hashArr[i] != null) {
index = i + 1;
return hashArr[i];
}
}
throw new NoSuchElementException();
}
}
This answer addresses your question about the iterator not returning all items.
The array index is never incremented, so it will always return the item at index 1, which is index + 1. index must be incremented in the call to next before returning so that the next call starts at the subsequent element in the backing array.
Also, the backing array is not dense (meaning there could be empty slots at arbitrary positions, and that's OK), so the next function has to find the next valid entry, not just give up if the next entry is empty (i.e. null).
Try this instead:
#Override
public Iterator<Tuple<T, S>> iterator() {
Iterator<Tuple<T, S>> it = new Iterator<Tuple<T, S>>() {
private int index = 0;
#Override
public boolean hasNext() {
for (int i = index; i < SIZE; ++i) {
if (hashArr[i] != null) {
return true;
}
}
return false;
}
#Override
public Tuple<T, S> next() {
for (int i = index; i < SIZE; ++i)
if (hashArr[i] != null) {
index = i + 1;
return hashArr[i];
}
}
throw new NoSuchElementException();
}
};
return it;
}
Here's a possible solution.
public boolean hasNext() {
for(; index < SIZE && hashArr[index] == null; index++);
return index < SIZE;
}
I have to implement an ArrayList and a sorting method for the list. The list is holding objects of the same type. When i try to sort the list using my own implementation I get this error:
The method insertionSort(T[]) in the type ArrayList is not applicable for the arguments (List)
I realize it wants an array passed to it, but how can I pass the list.. or just get it to work. I've been working on it for a while, checked my book, lecture notes, etc. and can't figure it out.
Student class(the objects the list will hold)
public class Student implements Serializable, Comparable<Student>
{
public int compareTo(Student other)
{
if (this.lastName.equals(other.lastName))
return this.firstName.compareTo(other.firstName);
else if (other.getlastName().compareTo(this.getlastName()) < 0)
return 0;
else if (other.getlastName().compareTo(this.getlastName()) > 0)
return -1;
else
return 1;
}
}
The actual ArrayList
public class ArrayList<T> implements Iterable<T>, List<T>
{
protected final int DEFAULT_CAPACITY = 20;
private final int NOT_FOUND = -1;
protected int rear;
protected T[] list;
#SuppressWarnings("unchecked")
public ArrayList()
{
rear = 0;
list = (T[])(new Object[DEFAULT_CAPACITY]);
}
public static <T extends Comparable<? super T>> void insertionSort(T[] a)
{
for(int index = 0; index < a.length; index++)
{
T key = a[index];
int position = index;
while(position > 0 && a[position-1].compareTo(key) > 0)
{
a[position] = a[position-1];
position--;
}
a[position] = key;
}
}
}
The easiest way I can think of, would be to modify your insertionSort method to take a List<T>. Something like,
public static <T extends Comparable<? super T>> void insertionSort(List<T> a) {
final int len = a.size(); // <-- from a.length
for (int index = 0; index < len; index++) {
T key = a.get(index); // <-- from a[index]
int position = index;
while (position > 0 && a.get(position - 1).compareTo(key) > 0) {
a.set(position, a.get(position - 1)); // from a[position] = a[position-1];
position--;
}
a.set(position, key); // <-- from a[position] = key;
}
}
If you want that method to apply only to your ArrayList:
public static <T extends Comparable<? super T>> void insertionSort(ArrayList<T> list)
{
T[] a = list.list;
...
take the whole list as parameter and get it's internal array directly
I am working on creating a bag of cards for a blackjack game in my CS course. This particular project requires that I create a bag to hold my 52 cards. Keep in mind that I am trying to assure that there are 4 types of each card, Queens, Kings, Jacks, and Aces all included. I keep getting an error in my main: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at Main.main(Main.java:14)
If anyone can please help me to get this bag running properly, it would be greatly appreciated.
Here is my code:
public class Bag<T>
{
T[] cards;
private final int DEFAULT_CAPACITY = 52;
private int numberOfEntries;
public Bag()
{
this.cards = (T[]) new Object[DEFAULT_CAPACITY];
numberOfEntries = DEFAULT_CAPACITY;
}
public int getCurrentSize()
{
return numberOfEntries;
}
public boolean isFull()
{
return numberOfEntries == DEFAULT_CAPACITY;
}
public boolean isEmpty()
{
return numberOfEntries == 0;
}
public boolean add(T newItem)
{
boolean result = true;
if(isFull())
{
result = false;
}
else
{
cards[numberOfEntries] = newItem;
numberOfEntries++;
}
return result;
}
public boolean remove()
{
boolean result = true;
if(numberOfEntries > 0)
{
numberOfEntries--;
}
else
result = false;
return result;
}
public void clear()
{
numberOfEntries = 0;
}
public int getNumOf(T anItem)
{
int count = 0;
for(int i = 0; i < cards.length; i++)
{
if(anItem.equals(cards[i]))
{
count++;
}
}
return count;
}
public boolean contains(T anItem)
{
boolean found = false;
for (int i = 0; !found && (i < numberOfEntries); i++)
{
if(anItem.equals(cards[i]))
{
found = true;
}
}
return found;
}
public T Grab()
{
int random = (int)(Math.random() * DEFAULT_CAPACITY);
if(!isEmpty())
{
cards[random] = null;
numberOfEntries--;
return cards[random];
}
else
return null;
}
public int getFrequencyOf(T anItem)
{
int counter = 0;
for(int i = 0; i < numberOfEntries; i++)
{
if(anItem.equals(cards[i]))
{
counter++;
}
}
return counter;
}
}
public class Main {
public static void main(String[] args)
{
//Accesses the Bag class
Bag<Integer> bag = new Bag<Integer>();
//Sets up 52 cards (13*4). 4 of each type
for (int i = 1; i <= 13; i++)
{
for (int j = 1; j <= 4; j++) {
bag.cards[i*j] = i;
//if the card is an ace and not equal to 1
if(i == 1)
bag.cards[i*j] = 11;
//handles the king, queen, and jack cards
else if (i==11||i==12||i==13)
bag.cards[i*j] = 10;
}
bag.add(1);
}
}
}
Don't provide access to your T[] cards variable. Make it private and create a set method in your Bag like this:
public void set(int index, T item) {
// assume !full AND 0 <= index < cards.length
this.cards[index] = item;
}
Then, instead of doing:
bag.cards[i*j] = 10;
you then do:
bag.set(i*j, 10);
The fact that you get a class-cast exception is because type erasure: your T[] only lives at compile time. After compilation, it will just have become a Object[]. That is why your direct access cards[0] = 123 throws this exception (Integer 123 cannot be put inside a Object[]).
The set(int index, T value) I suggested works, because after compilation, that will just become set(int index, Object value), and hence: no class-cast exception.
EDIT
You can test the following quick demo:
class Bag<T> {
private T[] cards;
public Bag() {
this.cards = (T[]) new Object[10];
}
public void set(int index, T value) {
this.cards[index] = value;
}
#Override
public String toString() {
return "Bag{cards=" + java.util.Arrays.toString(cards) + "}";
}
public static void main(String[] args) {
Bag<Integer> bag = new Bag<Integer>();
bag.set(0, 10);
bag.set(1, 20);
bag.set(2, 30);
System.out.println(bag);
}
}
on Ideone, which will print:
Bag{cards=[10, 20, 30, null, null, null, null, null, null, null]}
You can also simply remove the generics from your cards variable like this:
class Bag<T> {
private Object[] cards;
public Bag() {
this.cards = new Object[10];
}
public void set(int index, T value) {
this.cards[index] = value;
}
}
For inspiration, you can always have a look at the source of core Java classes that resemble your own. In this case, that would be the java.util.ArrayList: http://www.docjar.com/html/api/java/util/ArrayList.java.html
You cannot cast your Object array to a an Integer array, because its not, it's an Object array. That's what your (T[]) cast is trying to do:
this.cards = (T[]) new Object[DEFAULT_CAPACITY];
You cannot instantiate an array of type T either, unless you pass in the class type explicity - see What's the reason I can't create generic array types in Java?. Possible solutions:
Use Object [] to store you data, i.e. private Object[] cards;
Use a parameterized collections type like List<T>, i.e. private List<T> cards
So i am trying to make an array based generic heap that i can use with my tester class. Much of what i have is based of my understandings of trees and some research online as well as from my textbook; both which have very limited info on what i am looking for. However, i did manage to get all the methods in need and when i run it, i get this error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at q1.Heaps.<init>(Heaps.java:23)
at q1.createGui.<init>(Gui.java:46)
at q1.Gui.main(Gui.java:18)
Im guessing it has to do with how i declare and initialize my Comparable array, which i am having trouble figuring out how to.
package q1;
import java.util.Arrays;
public class Heaps<E extends Comparable<E>> {
Comparable[] data;
int size;
/**
* Constructor with s as size
*/
#SuppressWarnings("unchecked")
public Heaps(int s) {
size = 0;
data = (E[]) new Object[s];
}
/**
* Adds a value to the heap
*/
public void add(E value) {
if (full()) // expand array
ensureCapacity(2*size);
size++;
data[size] = value;
if (size > 1)
heapifyUp();
}
/**
* Checks if the array is full
*/
private boolean full()
{
return (size == data.length-1);
}
private void heapifyUp()
{
Comparable<E> temp;
int next = size;
while (next != 1 && data[next].compareTo(data[next/2]) > 0)
{
temp = data[next];
data[next] = data[next/2];
data[next/2] = temp;
next = next/2;
}
}
private void heapifyDown()
{
Comparable<E> temp;
int next = 0;
while (next*2 <= size) // node has a child
{
int child = 2*next; // left child
if (child < size &&
data[child].compareTo(data[child+1]) > 0)//left smaller than right
child++; // right child instead
if (data[next].compareTo(data[child]) > 0)
{
temp = data[next];
data[next] = data[child];
data[child] = temp;
next = child;
}
else;
next = size; // stop loop
}//end while
}
/**
* Removes all occurrence of element
*/
public boolean removeAll(E element) {
if (contains(element) && !(isEmpty())){
for (int i = 0; i < size; i++){
if(element.equals(data[i])){
data[i] = data[size-1];
}
heapifyDown();
}
return true;
}
return false;
}
/**
* Removes 1st occurrence of element
*/
public boolean remove(E element) {
if (contains(element) && !(isEmpty())){
for (int i = 0; i < size; i++){
if(element.equals(data[i])){
data[i] = data[size-1];
heapifyDown();
return true;
}
}
}
return false;
}
public boolean isEmpty() {
return size == 0;
}
public Comparable<E>[] ensureCapacity(int s) {
return Arrays.copyOf(data, 2*s);
}
/**
* Converts the heap into its String representation.
* #return the String representation
*/
public Comparable<E>[] iteratorPreOrder()
{
Comparable<E>[] temp = (E[]) new Object[size];
temp[0] = data[0];
int i = 1;
int count = 1;
while(data[2*i] != null){
temp[count] = data[2*i];
++i;
++count;
}
i = 1;
while(data[(2*i) +1] != null){
temp[count] = data[(2*i) +1];
++i;
++count;
}
return temp;
}
public int countOccurance(E element){
int count = 0;
for (int i =0; i < size; i++){
if(element.equals(data[i])){
count++;
}
}
return count;
}
public boolean contains (E element)
{
for (int i=0; i<size; i++){
if (element.equals(data[i])){
return true;
}
}
return false;
}
}
If you could please show me how i would solve this problem, i would greatly appreciate it. Thanks
EDIT: SO i edited the my class and now it works when i do data = (E[]) new Comparable[s]. So why does java not allow generic Array types, what makes it different from Arraylist, Stacks, Queues, and/or LinkedList which can be generic?
You are creating an Object[] and then trying to cast it to a Comprable[]. The compiler was telling you what you did wrong with the unchecked cast error.
You want data to be E[] data and the line to be:
data = new E[s];
Note: this could run into issues with how Java handles generics.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
Long story short, I am in a university Comp Sci class, and the Professor wants us to build a Vector but from scratch. Are their any good tutorials on the web for something like this? I did a Google search but nothing really came up.
EDIT
According to the document the teacher gave out the vector needs to be able to do the following:
append(Object element) – appending the element at the end of the vector
clear() – make the vector collection empty
contains(Object element) – check whether the vector contains the element
elementAt(int index) – access the element at the given index
indexOf(Object element) – find the index of the element
insertAt(int index, Object element) – insert the element at the given index
isEmpty() – check whether the vector is empty
removeAt(int index) – remove the element at the given index
remove(Object element) – remove the element from the vector
replace(int index, Object element) – replace the element at the given index with the given element
size() – get the number of elements in the current vector
ensureCapacity(int minCapacity) – make sure the vector gets at least the given capacity
clone() – returns a cloned copy of this vector
removeRange(int fromIndex, int toIndex) – removes from this vector all of the elements whose index is between fromIndex, inclusive and toIndex, exclusive
toString() – returns a string representation of this vector, containing the String representation of each element
reverse() – reverse the elements in this vector
merge(MyVector vector2) – add all the elements in vector2 to the end of this vector
Additionally the class needs to implment Cloneable and be self expanding.
This is what I have come up with so far:
package collection;
public class MyVector implements Cloneable {
protected Object[] items;
protected int arraySize;
protected int maxCap;
public MyVector (int initialCapacity) {
super();
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
this.items = new Object[initialCapacity];
this.arraySize = 0;
this.maxCap = initialCapacity;
}
public MyVector() {
this(10);
}
public void append(Object element) {
int newArraySize = this.arraySize + 1;
if(this.maxCap == newArraySize) {
this.items = this.increaseCap(newArraySize);
this.items[this.arraySize] = element;
this.arraySize += 1;
//System.out.println(this.items[this.arraySize);
} else {
this.items[this.arraySize] = element;
this.arraySize +=1;
}
}
#Override
public String toString() {
String output = "[";
//output = this.items[0].toString();
for(int i = 0; i < this.arraySize; i++) {
output += this.items[i] + ", ";
}
output += "]";
return output;
}
public void clear() {
for(int i = 0; i < this.arraySize; i++) {
this.items[i] = null;
this.arraySize = 0;
}
}
public boolean contains(Object element) {
boolean doesContain = false;
for(int i = 0; i < this.arraySize; i++) {
if(element == this.items[i]) {
doesContain = true;
i = this.arraySize;
}
}
return doesContain;
}
public Object elementAt(int index) {
if(this.arraySize >= index) {
return this.items[index];
} else {
Object temp = null;
System.out.println("No index of " + index);
return temp;
}
}
public Object indexOf(Object element) {
Object index = "No value found";
for(int i = 0; i < this.arraySize; i++) {
if(element == this.items[i]) {
index = i;
break;
}
}
return index;
}
public boolean isEmpty() {
if(this.arraySize == 0) {
return true;
}
return false;
}
public void replace(int index, Object element) {
if(this.arraySize > index) {
this.items[index] = element;
} else {
System.out.println("No element at " + index);
}
}
public int size() {
return this.arraySize;
}
public void reverse() {
Object[] temp = new Object[this.items.length];
int j = this.arraySize;
for(int i = 0; i < this.arraySize; i++) {
temp[j] = this.items[i];
j--;
}
this.items = temp;
}
public void ensureCapacity(int minCapacity) {
if(minCapacity > this.items.length) {
this.items = this.increaseCap(minCapacity);
}
}
public Object[] increaseCap(int minCap) {
Object[] arr1 = new Object[minCap * 2];
for(int i = 0; i < minCap; i++) {
arr1[i] = this.items[i];
}
this.maxCap = this.maxCap * 2;
return arr1;
}
#Override
public Object clone() {
return this.items;
}
public boolean checkIndex(int index) {
boolean check = false;
if(index < this.arraySize) {
check = true;
}
return check;
}
public void removeAt(int index) {
if(true == this.checkIndex(index)) {
Object[] temp = new Object[this.arraySize - 1];
for(int j = 0; j < index; j++) {
temp[j] = this.items[j];
}
for(int j = index + 1; j < this.arraySize; j++) {
temp[j-1] = this.items[j];
}
this.items = temp;
this.arraySize = this.arraySize - 1;
}
}
public void insertAt(int index, Object element) {
if (this.checkIndex(index) == true) {
Object[] temp = new Object[this.arraySize];
for(int i = index; i < this.arraySize; i++) {
temp[i+1] = this.items[i];
}
this.items[index] = element;
for (int i = index + 1; i < this.arraySize; i++) {
this.items[i] = temp[i - 1];
}
this.arraySize = this.arraySize - 1;
}
}
public void remove(Object element) {
for(int i = 0; i < this.items.length; i++) {
if(this.items[i] == element) {
this.removeAt(i);
}
}
}
public void removeRange(int fromIndex, int toIndex) {
for(int i = fromIndex; i < toIndex; i++) {
this.removeAt(i);
}
}
public void merge(MyVector vector2) {
this.ensureCapacity(vector2.size() + this.arraySize);
for(int i = 0; i < vector2.size(); i++) {
this.append(vector2);
}
}
}
Assuming your assignment is replicating java.util.Vector, I would look at what a Vector is in order to replicate it:
Vector implements a dynamic array. It is similar to ArrayList, but
with two differences:
Vector is synchronized.
Vector contains many legacy methods that are not part of the collections framework.
You could attempt to use an ArrayList in a synchronous manner in order to replicate a Vector, but I'm sure there are much better solutions.