So I am a college student just looking for a little help and understanding, I have a professor that does not allow us to use java pre-written classes such as ArrayList, so I am trying to figure out how to modify my current encapsulated array class to use generics so that I don't have to do so much casting in the application class of my program
public class ArrayClass {
private Object[] objArray;
private int index = 0;
public static final int MAX_SIZE = 100;
public ArrayClass(){
objArray = new Object[100];
}
public ArrayClass(int numSlots){
objArray = new Object[numSlots];
}
public ArrayClass(Object[] anArray, int newIndex){
objArray = new Object[newIndex];
for(int i=0; i<newIndex; i++){
objArray[i] = anArray[i];
}
index = newIndex;
}
//return object array, accessor
public Object[] getstrArr(){
return objArray;
}
//return # of actual data in array, accessor
public int getIndex(){
return index;
}
//return an object at given pos, accesor
public Object getObject(int pos){
return objArray[pos];
}
//assign a new object array, mutator
public void setObjArr(Object[] aStrArr){
for(int i=0; i<index; i++){
objArray[i] = aStrArr[i];
}
}
//assign a new index, mutator
public void setIndex(int anIndex){
index = anIndex;
}
//insert a new string into the array if there is room, increment index
public void add(Object someObj){
if(index < objArray.length){
objArray[index] = someObj;
index++;
}
}
//return the string with contents of array
public String toString(){
String output = " ";
for(int i=0; i<index; i++){
output = output + objArray[i].toString();
}
return output;
}
//return true if calling object is equivalent to argument
public boolean equals(Object someObj){
for(int i=0; i< index; i++){
if(objArray[i].equals(someObj))
return true;
}
return false;
}
}
public class ArrayClass<E> {
// return object array, accessor
public <T> T[] getstrArr(T[] t) {<--This is done because arrays are covarant in nature
return (T[]) Arrays.copyOf(objArray, index, t.getClass());
}
// return an object at given pos, accesor
public E getObject(int pos) {<-- For single elements just return E with casting
return (E) objArray[pos];
}
Implementation Notes
Length checks should be considered for Arrays.copy of
You can read a nice article about generics
Well, i would not expose your index with methods like setIndex, etc. Not adding null element check too.
Anyway, I would make something like:
public class ArrayClass<E> {
...
private E[] elements;
private int index;
...
public ArrayClass() {
this.elements = (E[]) new Object[MAX_SIZE];
this.index = 0;
}
// this constructor substitutes the method setObjArr
public ArrayClass(E[] elements) {
this.elements = elements;
this.index = elements.length;
}
...
public void add(E element) {
if (needsToGrow()) {
duplicateArraySize();
}
this.elements[index++] = element;
}
private boolean needsToGrow() {
return index + 1 == elements.length;
}
private void duplicateArraySize() {
E[] extendedArray = (E[]) new Object[this.elements.length * 2];
System.arraycopy(elements, 0, extendedArray, 0, elements.length);
this.elements = extendedArray;
}
public E get(int index) {
return this.elements[index];
}
public int size() {
return this.index;
}
...
}
I would do it like that:
public class ArrayClass<T> {
public T[] objArray;
private int index = 0;
public static final int MAX_SIZE = 100;
#SuppressWarnings("unchecked")
public ArrayClass(Class<T> c) {
objArray = (T[]) Array.newInstance(c,MAX_SIZE);
}
}
and so on.
And then:
ArrayClass<String> myStringArray = new ArrayClass<String>(String.class);
Related
I have created in class a generic class that works like ArrayList. The class included an array that gets bigger and smaller by demand by functions. Now, I have to implement the List interface and got stuck on the Iterator and ListIterator. I get only errors all the time, when I try to realize methods that depends on Iterator or ListIterator. Of course I have searched on the internet but I think I miss something.
public class EviatarList implements List, Iterable {
private E[] arr;
private static final int DEFAULT_CAPACITY = 3;
private int index = 0;
private int iteratorIndex = 0;
#Override
public Iterator<E> iterator() {Iterator<E> it = new Iterator<E>() {
#Override
public boolean hasNext() {
return index < arr.length && arr[index + 1] != null;
}
#Override
public E next() {return arr[iteratorIndex++];}
#Override
public void remove(){
E [] arr1 =(E[]) new Object [size()-1];
try {
arr[iteratorIndex] = null;
iteratorIndex--;
index--;
for (int i = 0, j = 0; i < arr.length; i++, j++) {
if (arr[i] != null)
{
arr1[j] = arr[i];
} else{
j--;
}
}
} catch (Exception e)
{
System.out.println(e.getMessage());
}
arr = arr1;
}
};
return it;
}
public ListIterator<E> listIterator() {
ListIterator<E> li = new ListIterator<E>() {
//o(1)
#Override
public boolean hasNext() {
return index < arr.length;
}
//o(1)
#Override
public E next() {
return arr[index++];
}
//o(1)
#Override
public boolean hasPrevious() {
return index > 0;
}
//o(1)
#Override
public E previous() {
return arr[index--];
}
//o(1)
#Override
public int nextIndex() {
return iteratorIndex;
}
//o(1)
#Override
public int previousIndex() {
return iteratorIndex--;
}
// o(n)
#Override
public void remove() {
E[] newArr = (E[]) new Object[arr.length - 1];
index--;
for (int i = 0, j = 0; i < index; i++, j++) {
if (i != iteratorIndex) {
newArr[i] = arr[j];
} else {
j--;
}
}
arr = newArr;
}
Sorry, but your question is a little vague so I cannot really answer. The implementation of EviatarList is not shown but used (e.g. size()) and "I get only errors all the time" is not clear about the kind of errors (from the compiler or runtime using it, ...).
Some thoughts on your implementation that may help one step further:
Why you implement your own List instead of extending AbstractList (that would offer ready to use iterators)?
You can have multiple iterators on the same collection, therefore the iteratorIndex has to be state (aka member) of the Iterator, not of the List!
There is some confusion about index and iteratorIndex in your implementation. What is the difference and what is the role of index?
As ListIterator extends Iterator it would simplify your implementation using the same for both:
public Iterator<E> iterator() {
return listIterator();
}
I am trying to figure out how to store the values of tst.insert() and tsttxt.insert() into an array. So far the only thing I have been able to do is have the program recognize that they are there. When I try to print the variables I get the last value of tst.insert(). I am assuming that the last value is displayed because the other values are being overridden.
public class genericdrive {
public static void main(String[] args) {
collection<Integer> tst = new collection<>();
collection<String> tsttxt = new collection<>();
//System.out.println("If collection is empty return true: " + tst.isEmpty());
tst.insert(45);
tst.insert(43);
tst.insert(90);
tsttxt.insert("Jeff");
tsttxt.insert("Rey");
}
}
..
public class collection<T> extends genericdrive {
private T element;
private T[]array;
// collection<T> objt = new collection<>();
public void set(T element) {
this.element = element;
}
public T get() {
return element;
}
public <T> void insert(T i) {
i = (T) element;
//array[0]=<T> i;
}
}
considering that array variable holds all the elements the insert function you wrote does not push any value into it.
It is a workaround if the private variable is expected to be an array.
Try the following:
public class MyCollection<T> {
private T element;
private T[] array;
MyCollection(){
array = (T[]) Array.newInstance( Comparable.class , 0);
}
public void set(T element) {
this.element = element;
}
public T get() {
return element;
}
public void insert(T i) {
T[] temp = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + 1);
temp[array.length] = i;
System.arraycopy(array, 0, temp, 0, array.length);
array = temp;
}
}
The goal of my program is to store data for students(First Name, Last Name, ID#).I'm trying to create 4 Arrays. One array will hold the combined value of each student object that I'm adding(myDB). The other 3 hold indexes to the original spot of each value(Fname,Lname,ID) and add them to an ordered array without sorting the array. The trouble I'm having is that once I add something to the Index Arrays and go to print them, it prints all of the IDs regardless of what object I call.
//class containing methods to list, add, and delete
//Class that declares the main database array that holds all three (ID,First,Last)
import java.io.FileInputStream;
import java.util.*;
public class DataBase
{
private String tempID, tempFname, tempLname;
private DataBaseArray myDB;
private int nextDBRecord;
private IndexArray ID;
private IndexArray First;
private IndexArray Last;
public DataBase()
{
nextDBRecord = 0;
myDB =new DataBaseArray(100);
ID=(new IndexArray(100));
First=new IndexArray(100);
Last=new IndexArray(100);
}
void addData(String last, String first, String id)
{
tempLname = new String(last);
tempFname = new String(first);
tempID = new String(id);
//ID.insert(new IndexRecord(tempID, nextDBRecord));
First.insert(new IndexRecord(tempFname,nextDBRecord));
Last.insert(new IndexRecord(tempLname,nextDBRecord));
//Adds to main DB with
myDB.getStudentArray()[nextDBRecord]= (new DataBaseRecord(tempLname,tempFname,tempID));
System.out.println(myDB.getStudentArray()[nextDBRecord]);
nextDBRecord++;
}
void addIt ()
{
Scanner keyb = new Scanner(System.in);
System.out.println("Please enter the ID for new student entry");
tempID=keyb.next();
ID.insert(new IndexRecord(tempID, nextDBRecord));
System.out.println("Please enter the first name of the new student");
tempFname=keyb.next();
First.insert(new IndexRecord(tempFname, nextDBRecord));
System.out.println("Please eneter the last name of the new student");
tempLname=keyb.next();
Last.insert(new IndexRecord(tempLname,nextDBRecord));
//Adds to main DB with
myDB.getStudentArray()[nextDBRecord]= (new DataBaseRecord(tempLname,tempFname,tempID));;
nextDBRecord++;
}
void findIt()
{
}
void list (int type, int order)
{
First.printIt(order);
}
}
//Class that creates the objects to add to Iarray Farray Iarray
//IndexArray is a static array
//Creates a single entry into the IndexArray
//Need a compareTo method that gives the where value of each object
public class IndexRecord
{
private String key; //Value
private int where; //Where it is at in DataBaseArray
IndexRecord (String value, int position)
{
setKey(new String(value));
where = position;
}
public String toString()
{
return getKey()+" "+ String.valueOf(where);
}
public String getKey() //Getter for key value of the new student that is being added
{
return key;
}
public void setKey(String key) //Setter for key value of the new student that is being added
{
this.key = key;
}
}
//Same as OrderedArray Class
//Add Iterator methods. Instead of printing here, tell DataBase class what DatabaseRecord objects to print
public class IndexArray
{
private static IndexRecord[] irArray;
private int nOfElem; //Should be the same for each array so only 1 counter is needed
private int maxSize;
private int theIterator;
public IndexArray(int size)
{
nOfElem = 0;
maxSize=size;
irArray = new IndexRecord[size];
}
//-----------------------------Getters and Setters-------------------------------------
public int size() //Getter to find num of elements in array that can be called in other class
{ return nOfElem; }
public IndexRecord[] getIRarray()
{
return irArray;
}
//---------------------Iterator Methods-----------------------------------------------------
void iteratorToFront()
{
theIterator=(nOfElem>0? 0 : -1);
}
void iteratorToBack()
{
theIterator=(nOfElem>0 ? nOfElem-1 : -1);
}
boolean hasNext()
{
return (theIterator==nOfElem-1? false:true );
}
boolean hasPrevious()
{
return (theIterator==0? false : true);
}
public IndexRecord getIterator()
{
return(theIterator==-1 ? null :irArray[theIterator]);
}
int getNext()
{
theIterator=(hasNext()? theIterator+1: -1);
return(theIterator==-1? null : theIterator);
}
int getPrevious()
{
theIterator=(hasPrevious()? theIterator-1:-1);
return (theIterator==-1? null : theIterator);
}
//------------------Methods Called In Main---------------------------------------
public boolean insert(IndexRecord ir)
{
if(maxSize==nOfElem) return false;
int j;
for(j=nOfElem-1;j>=0;j--)
{
if(irArray[j].getKey().compareToIgnoreCase(ir.getKey())<0)break;
{
irArray[j+1]=irArray[j]; //Pushes all objects down to make room for new one
}
}
irArray[j+1]=ir;
nOfElem++;
return true;
}
public int find(String searchKey)
{
int lowerBound = 0;
int upperBound = nOfElem-1;
int currentRef;
while(true)
{
currentRef = (lowerBound + upperBound) / 2;
String tempValue = String.valueOf(irArray[currentRef].getKey());
if(tempValue.compareTo(searchKey) == 0)
return currentRef;
else if (lowerBound > upperBound)
return nOfElem; //returns a pointer to an empty slot
else
{
if(tempValue.compareTo(searchKey) > 0)
lowerBound = currentRef++;
else
upperBound = currentRef - 1;
}
}
}
//delete
public void printIt(int order)
{
switch(order)
{
case -1:
iteratorToBack();
break;
case 1:
iteratorToFront();
while(hasNext())
{
System.out.println(irArray[getNext()]);
}
break;
default:
}
}
}
I've added to my project a new data structure Heap<Integer,Integer> but the only problem I've got is that it prints me only one time the result.
If I have the input:
v=10;new(v,20);new(a,22);print(v)
at the end of execution
Heap={1->20, 2->22},
SymTable={v->1, a->2}
But what it gives me:
Heap: 1->22
SymTable: a -> 1
v -> 1
It overrides the first value.Here is the code from the controller where is the main part:
HeapAllocation crtStmt1=(HeapAllocation) crtStmt;
String varI = crtStmt1.getVarname();
Exp e = crtStmt1.getExpression();
int i=0;
Id<Object,Integer> tbl = state.getDict();
IHeap<Integer,Integer> heap1 = state.getHeap();
int value= e.eval(tbl, heap1);
heap1.put(++i, value);
if (tbl.containsKey(varI))
tbl.update(varI,i);
tbl.update(varI, i);
The problem I guess is after this line:
heap1.put(++i, value);
because for a new operation it doesn't append to the previous one, just overrides it.
Edit:
The implementation of the heap:
public class Heap<Integer,In> implements IHeap<Integer, Integer>,Serializable{
private Map<Integer, Integer> mapp;
public Heap(){
mapp = new HashMap<Integer,Integer>();
}
public void put(Integer index, Integer value){
mapp.put(index, value);
}
public void remove(Integer index){
try{
if(isEmpty())
throw new ExceptionRepo();
else
mapp.remove(index);
}catch (ExceptionRepo ex){
System.err.println("Error: Heap is empty.");
}
}
public boolean isEmpty(){
return mapp.isEmpty();
}
public Integer get(Integer index){
return mapp.get(index);
}
public boolean containsIndex(Integer index){
return mapp.containsKey(index);
}
public void update(Integer index, Integer value){
mapp.put(index, value);
}
public String toString(){
Set<Integer> all = mapp.keySet();
Object[] keysA= all.toArray();
String res="";
for(int i=0; i<mapp.size(); i++){
Integer v = mapp.get(keysA[i]);
res += keysA[i].toString() + "->" + v.toString() + "\r\n";
}
return res;
}
}
Edit2: Maybe the problem is in the eval function implementation.To be clear, I have a Exp class:
public class Exp{
public int eval(Id<Object,Integer> tbl)throws ExceptionRepo{
return 0;
}
public String toString(){
return "";
}
public int eval(Id<Object,Integer> tbl,IHeap<Integer,Integer> heap) throws ExceptionRepo{
return 0;
}
And some derived classes that extends the Exp class.I added a new method in the ConstExp class:
public class ConstExp extends Exp implements Serializable{
int number;
public int eval(Id<Object,Integer> tbl) throws ExceptionRepo{
return number;
}
public ConstExp(int n){
number = n;
}
public String toString(){
return "" + number;
}
public int eval(Id<Object,Integer> tbl,IHeap<Integer,Integer> heap) throws ExceptionRepo{
return number; //THIS IS THE NEW METHOD
}
This class should return a value..so for "v=20", after execution of the statement it puts the value 20 in the v based on this class implementation.
If it's useful this is the statement evaluation rule for the heap(that I implemented in the controller up there):
Stack1={new(var,exp)| Stmt2|...}
SymTable1
Heap1
==>
Stack2={Stmt2|...}
let be v=eval(exp,SymTable1,Heap1) in
Heap2 = Heap1 U {newfreelocation ->v}
if var exists in SymTable1 then SymTable2 = update(SymTable1,
var,newfreelocation)
else SymTable2 = add(SymTable1,var, newfreelocation)
How to resolve this?
I am trying to build a simple generic class that uses generic objects in java. everything compiles fine, but when i run the code, it doesn't display the objects i passed to it.
Here is my code:
public class ListDriver {
public static void main(String[] args) {
List<String> glist = new List<String>(10);
glist.add("milk");
glist.add("eggs");
System.out.println("Grocery List" + glist.toString());
}
public class List<T> {
private T[] datastore;
private int size;
private int pos;
public List(int numElements) {
size = numElements;
pos = 0;
datastore = (T[]) new Object[size];
}
public void add(T element) {
datastore[pos] = element;
}
public String toString() {
String elements = "";
for (int i = 0; i < pos; ++i) {
elements += datastore[i] + "";
}
return elements;
}
}
}
You don't increment your pos variable, so you're always adding in the same place. Try
public void add(T element) {
datastore[pos++] = element;
}
Your add method always replaces the element in position 0 (zero). You forgot to increment pos (pos++;)