I'm trying to write a Linear List based on arrays, but make the list be able to store any value by using Java Generics. This way I can create other programs that utilize it, but pass in different data types. I'm not entirely sure how to do this, any help would be appreciated.
I guess Im struggling trying to set it up and create the functions. The generic type really messes me up.
For example, trying to add a removeFirst() function, I cant use a loop like this:
for (int i = 0; i < n - 1; i++)
newList[i] = newList[i + 1];
— as it says The type of the expression must be an array type but it resolved to ArrayList.
Fair warning, I'm still learning data structures. This is what I have so far:
import java.util.ArrayList;
public class LinearList<T> {
private static int SIZE = 10;
private int n = 0;
private final ArrayList<T> newList = new ArrayList<T>(SIZE);
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public void add(T value, int position) {
newList.add(position, value);
n++;
}
public void addFirst(T value) {
newList.add(0, value);
n++;
}
public void removeLast() {
T value = null;
for (int i = 0; i < newList.size(); i++)
value = newList.get(i);
newList.remove(value);
n--;
}
public void removeFirst() {
newList.remove(0);
n--;
}
public T first() {
return newList.get(0);
}
public T last() {
int value = 0;
for (int i = 0; i < newList.size() - 1; i++)
value++;
return newList.get(value);
}
public int count() {
return n;
}
public boolean isFull() {
return (n >= SIZE);
}
public boolean isEmpty() {
return (n <= 0);
}
//part 4
public void Grow() {
int grow = SIZE / 2;
SIZE = SIZE + grow;
}
public void Shrink() {
int grow = SIZE / 2;
SIZE = SIZE - grow;
}
public String toString() {
String outStr = "" + newList;
return outStr;
}
}
A good start would be to make it non-generic with a class you are comfortable with, such as an Integer.
Once you have it set up, you can then make it generic by adding <T> to the class name, then replacing all references of Integer with T.
public class MyArray{ becomes public class MyArray<T>{
public Integer add(Integer value){ becomes public T add(T value){
See What are Generics in Java? for more help
Related
I have a question for the more advanced OOP developers here.
I am currently a CS student. We learned a Procedural Programming in Java the first semester where ADT was introduced. I understand the theory and the idea of why ADT is good and what are the benefits of it but it seems quite difficult for me to implement it in code. I get confused and lost.
In addition to that our exit test was on paper (we had to write around 200 line of code on paper) and I found it difficult.
Are there any tips before starting to construct the program?
For instance, do you guys already know how many methods and what method what it will return and have as a formal argument before you start to write the code?
You can approach it programming-style.
First, you need to define an interface for the ADT. Just write down its name and what it does.
Example:
ADT: Integer Stack
void push(int element) - adds an element to the top of stack
int pop() - removes and returns an element from the top of stack
int peek() - returns the value of top. no removal of value
boolean isEmpty() - returns true if the stack is empty
int size() - returns the number of element in the stack.
void print() - print all values of stack
Next is you need to decide on its implementation. Since ADT is about storage, it will be good to decide on storage strategy first.
Example:
ADT: Integer Stack
Implementation: Array Integer Stack
Implements an int stack using Java's built-in array functionality.
Since array is a static collection, i need to use an integer variable to track "top"
When everything is set, you can now proceed to coding.
public interface IntegerStack {
void push(int e);
int pop();
int peek();
boolean isEmpty();
int size();
void print();
}
public class ArrayIntegerStack implements IntegerStack {
private static final int INITIAL_TOP_INDEX = -1;
private int topIndex = INITIAL_TOP_INDEX;
private int[] stackValue = new int[Integer.MAX_VALUE];
#Override
public void push(int element) {
stackValue[++topIndex] = element;
}
#Override
public int pop() {
return stackValue[topIndex--];
}
#Override
public int peek() {
return stackValue[topIndex];
}
#Override
public boolean isEmpty() {
return INITIAL_TOP_INDEX == topIndex;
}
#Override
public int size() {
return topIndex + 1;
}
#Override
public void print() {
for (int i = 0; i <= topIndex; i++) {
System.out.println(stackValue[i]);
}
}
}
Adding on to the answer of KaNa001, you could use a modified HashMap where the key is the index and the value is the integer in the stack. This wont cause an Exception, as the HashMap object can change its length.
public class OrderSet<T> {
private HashMap<Integer, T> array;
public OrderSet() {
array = new HashMap<Integer, T>();
}
public void addAt (T o, int pos) {
// uses Array indexing
HashMap<Integer, T> temp = new HashMap<Integer, T>();
if (!(array.size() == 0)) {
for (int i = 0; i < array.size(); i++) {
temp.put(i, array.get(i));
}
array.put(pos, o);
int size = array.size();
for (int i = pos + 1; i < size + 1; i++) {
array.put(i, temp.get(i - 1));
}
} else {
array.put(0, o);
}
}
public T getPos (int pos) {
if (array.size() == 0) {
return null;
} else {
return array.get(pos);
}
}
}
I'm working on a program to manipulate chemical formulae, and I'm writing a method which needs to loop through an ArrayList called "terms" and return the first one alphabetically.
e.g. terms = {Term('H',4),Term('C',2),Term('H',4),Term('C',1)} would return Term('C',2)
I've written this code so far but it's not working. I'm a real beginner to the Java language.
public Term nextElement()
{
int i = 0;
for (i = 0; i < terms.size()-1; i++)
{
int j = 1;
while (i + j <= terms.size())
if (terms.get(i).getElement() > terms.get(i+j).getElement())
{
terms.remove(i+j++);
return terms.get(i);
}
}
return null;
}
I'd appreciate any ideas or suggestions to solve this problem. Thanks!
You have two options here:
Let your Term class implement Comparable interface and override its compareTo() method. Then you can use Collections.sort(listOfTerms) to sort them and loop through.
Add class TermComparator which implements Comparator interface, use Collections.sort(listOfTerms, new TermComparator()) and loops through the sorted list.
1- you can implement Comparable and override compareTo()
int compareTo(Object obj){
Term term = (Term)obj;
if(term.getElement < this.getElement())
return 1;
else if (term.getElement == this.getElement())
return 0;
else
return -1;
}
then use
Collection.sort(terms);
2-
public Term nextElement()
{
char minElement = 'Z';
int index = 0;
for (int i = 0; i < terms.size(); i++)
{
if (terms.get(i).getElement() < minElement)
{
minElement = terms.get(i).getElement();
index = i;
}
}
Term temp = terms.get(index);
terms.remove(index)
return temp;
}
use Collections.sort(terms);it will arrange the list alphabetically.
This is what you need to do:
List<Term> terms = //your list
Collections.sort(terms, new Comparator<Term>() {
#Override
public int compare(Term t1, Term t2) {
return t1.getElement().compareTo(t2.getElement());
}
});
CODE:
public class CodeSample {
public static void main(String[] args) {
List<Term> terms=new ArrayList<Term>();
terms.add(new Term('H',4));
terms.add(new Term('C',2));
terms.add(new Term('H',4));
terms.add(new Term('C',1));
System.out.println("Before Sorting");
for(Term term:terms){
System.out.print(term.toString().concat(" "));
}
Collections.sort(terms,new Comparator<Term>() {
#Override
public int compare(Term object1, Term object2) {
if (object1.getElement() != object2.getElement()) {
return object1.getElement() - object2.getElement();
} else {
return object2.getCount() - object1.getCount();
}
}
});
//Sorted terms
System.out.println("After Sorting");
for(Term term:terms){
System.out.print(term.toString().concat(" "));
}
}
public static class Term{
private char element;
private int count;
public Term(char element, int count) {
super();
this.element = element;
this.count = count;
}
public char getElement() {
return element;
}
public int getCount() {
return count;
}
#Override
public String toString() {
return "Term [element=" + element + ", count=" + count + "]";
}
}
}
OUTPUT:
Before Sorting
Term [element=H, count=4] Term [element=C, count=2] Term [element=H, count=4] Term [element=C, count=1]
After Sorting
Term [element=C, count=2] Term [element=C, count=1] Term [element=H, count=4] Term [element=H, count=4]
For class I had to either implement a BST or a heapSort. I did the BST but figured it would be good to know this too but now I'm stuck. This is my first time working with heaps(and really coding with generics/implementing Comparable so I apologize for all the errors) and im running into an issue implementing compareTo.
Essentially I want to be able to add generic objects to my heap Array and then compare them for the Heap sorting. I use compareTo to check a new entry when adding to the heap and for swapping in the reheap method.
My errors returned:
Heap.java:64: error: bad operand types for binary operator '<'
if (this < other)
^
first type: Heap<T>
second type: Heap<T>
where T is a type-variable:
T extends Comparable<T> declared in class Heap
Im not sure how to work around that though. I understand that my binary operator isnt for generics but I dont know how to work around it.
Thanks for any input. Sorry about all the beginners mistakes you may find!
Heres my code:
import java.util.*;
class Heap<T extends Comparable <T>> implements Comparable<Heap<T>>{
private T[] heap;
private int lastIndex;
private static final int CAPACITY = 25;
public Heap(){
this(CAPACITY);
}
public Heap(int capacity){
heap = (T[])new Comparable[capacity+1];
lastIndex = 0;
}
public void add(T newEntry){
lastIndex++;
if(lastIndex>=heap.length)
doubleArray();
int newIndex = lastIndex;
int parentIndex = newIndex/2;
while((parentIndex>0)&&(heap[parentIndex].compareTo(newEntry)>0))
{
heap[newIndex] = heap[parentIndex];
newIndex = parentIndex;
parentIndex = newIndex/2;
}
heap[newIndex] = newEntry;
}
public void display()
{
for(int i=1;i<heap.length;i++)
{
System.out.println(heap[i]);
}
}
private void doubleArray()
{
T[] oldHeap = heap;
int oldSize = heap.length;
heap = (T[]) new Object[2*oldSize];
for(int i =0; i < oldSize-1;i++)
{
heap[i] = oldHeap[i];
}
}
public int compareTo(Heap<T> other)
{
int sort = 0;
if (this < other)
{
sort = -1;
}
else if (this> other)
{
sort = 1;
}
else
{
sort = 0;
}
return sort;
}
private <T extends Comparable<T>> void reheap(T[] heap, int rootIndex, int lastIndex)
{
boolean done=false;
T orphan = heap[rootIndex];
int leftChildIndex = 2 * rootIndex + 1;
while(!done && (leftChildIndex<=lastIndex))
{
int largerChildIndex = leftChildIndex;
int rightChildIndex = leftChildIndex + 1;
if(rightChildIndex<=lastIndex && (heap[rightChildIndex].compareTo(heap[largerChildIndex])>0))
largerChildIndex = rightChildIndex;
if(orphan.compareTo(heap[largerChildIndex])<0)
{
// System.out.println(orphan+ "--" + largerChildIndex);
heap[rootIndex] = heap[largerChildIndex];
rootIndex = largerChildIndex;
leftChildIndex = 2 * rootIndex+1;
}
else
done = true;
}
heap[rootIndex] = orphan;
}
public <T extends Comparable<T>> void heapSort(int n)
{
for(int rootIndex = n/2-1;rootIndex >=0;rootIndex--)
reheap(heap,rootIndex,n-1);
swap(heap,0,n-1);
for(int lastIndex = n-2;lastIndex > 0;lastIndex--)
{
reheap(heap,0,lastIndex);
swap(heap,0,lastIndex);
}
}
private <T extends Comparable<T>> void swap(T[] a,int first, int last)
{
T temp;
temp = a[first];
a[first] = a[last];
a[last] = temp;
}
}
Any help with any of this is very very appreciated
You don't want your heap to be Comparable; you want to compare its members. Therefore remove implements Comparable<Heap<T>> from your class declaration and remove the compareTo method.
Many of your methods (reheap, heapSort, swap) redundantly declare <T extends Comparable<T>> where you are already in the context of your class parameterized with T. Remove those declarations.
I think you need to implement the compareTo on you T object, not on the heap itself. You have to
make sure T is comparable for it to be in the heap.
Is there a way to implement a loop using final variables?
I mean a loop that would run for a specified number of iterations when you are not allowed to change anything after initialization!
Is recursion allowed, or do you literally need a loop construct like for or while? If you can use recursion, then:
void loop(final int n) {
if (n == 0) {
return;
} else {
System.out.println("Count: " + n);
loop(n-1);
}
}
One way is to create an Iterable<Integer> class representing an arbitrary range (without actually having to store all of the values in a list):
public static class FixedIntRange implements Iterable<Integer> {
private final int min;
private final int max;
public FixedIntRange(final int min, final int max) {
this.min = min;
this.max = max;
}
#Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private Integer next = FixedIntRange.this.min;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public Integer next() {
final Integer ret = next;
next = ret == max ? null : next + 1;
return ret;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
and then iterate over it normally:
for (final int i : new FixedIntRange(-10, 20)) {
// this will be run for each i in the range [-10, 20]
}
Create an array whose size is the required number of iterations, then use it in a for-each loop:
public class Test {
public static void main(String[] args) {
final int N = 20;
final int[] control = new int[N];
for(final int i : control){
System.out.println(i);
}
}
}
The trick here is that the iteration indexing is generated by the compiler as part of the enhanced for statement, and does not use any user-declared variable.
Something like this -
final int max = 5;
for(int i=0; i<max; i++) {}
Or another interesting one-
final boolean flag = true;
while(flag) {
// keep doing your stuff and break after certain point
}
One more-
List<String> list = ......
for(final Iterator iterator = list.iterator(); iterator.hasNext(); ) {
}
How do I write a constructor to change ints to ints or longs or strings....I am making a Memory system and I have code for Memory and a Memory Element (MemEl) and my test code and I am trying to write these constructors: MemEl(int), MemEl(long), MemEl(String) I already have done it for shorts and bytes but I need some help with these. Thanks.
Here is my Memory code:
class Memory{
private MemEl[] memArray;
private int size;
public Memory(int s)
{size = s;
memArray = new MemEl[s];
for(int i = 0; i < s; i++)
memArray[i] = new MemEl();
}
public void write (int loc, int val)
{if (loc >=0 && loc < size)
memArray[loc].write(val);
else
System.out.println("Index Not in Domain");
}
public MemEl read (int loc)
{return memArray[loc];
}
public void dump()
{
for(int i = 0; i < size; i++)
if(i%1 == 0)
System.out.println(memArray[i].read());
else
System.out.print(memArray[i].read());
}
}
Here is my Memory Element Code:
class MemEl{
private int elements;
public Memory MemEl[];
{
elements = 0;
}
public void MemEl(byte b)
{
elements = b;
}
public void MemEl(short s)
{
elements = s;
}
public int read()
{
return elements;
}
public void write(int val)
{
elements = val;
}
}
Here is my Test code
class Test{
public static void main(String[] args)
{
int size = 100;
Memory mymem;
mymem = new Memory(size);
mymem.write(98,4444444);
mymem.write(96,1111111111);
MemEl elements;
elements = mymem.read(98);
System.out.println(mymem);
mymem.dump();
}
}
If you can afford to lose precision, then you can cast:
public MemEl(long longValue) {
elements = (int) longValue;
}
and parse:
public MemEL(String str) {
elements = Integer.parseInt(str);
}
elements is an int. byte and short can be cast implicitly (without you knowing) to int. long and String can't, hence you will not be able to add a constructor to the MemEl class