Deep copying Generics in Java - java

I have a programming assignment to make a generic stack in Java and I need to make a deep copy of newNode T. I don't know how to make a method deep Copy that can access its self and output i'`s deep copy. So far, I have this:
public class Stack<T>
{
private T[] data;
private int top;
private int size;
public Stack( )
{ top = -1;
size = 100;
data = (T[])new Object[100];
}
public Stack(int n)
{ top = -1;
size = n;
data = (T[])new Object[n];
}
public boolean push(T newNode)
{ if(top == size-1)
return false; // ** overflow error **
else
{ top = top +1;
data[top] = newNode.deepCopy();
return true; // push operation successful
}
}
public T pop( )
{ int topLocation;
if(top == -1)
return null; // ** underflow error **
else
{ topLocation = top;
top = top -1;
return data[topLocation];
}
}
public void showAll( )
{ for(int i = top; i >= 0; i--)
System.out.println(data[i].toString());
}
}
How can I make the deep copy of newNode. I'm pretty sure I need an interface for the method but past that I`m lost.

Perhaps the most general and straight forward solution would consist in asking the using code to provide the deep-copying routine at construction:
public class Stack<T> {
...
private final Function<T, T> elementCopier;
public Stack<T>(Function<T, T> elementCopier) {
// make sure thy are not passing you a null copier:
this.elementCopier = Objects.requiresNonNull(elementCopier);
...
}
...
public boolean push(T element) {
...
data[top] = elementCopier.apply(element);
...
}
...
}
So for example for a cloneable class type where .clone() is in fact a deepCopy the user code would be like:
Stack<MyElemClz> stack = new Stack<>(x -> x.clone());
// or:
Stack<MyElemClz> stack = new Stack<>(MyElemClz::clone);
...
MyElemClaz elem = ...;
...
stack.push(elem);
If the type is an constant simple object like and String there is no need for clonning, in that case the user would indicate identity lambda x -> x as
the copier:
Stack<String> stack = new Stack<>(x -> x)
If the user insists in making a copy even when the class is a constant you can force it:
Stack<String> stack = new Stack<>(x -> new String(x))
// or
Stack<String> stack = new Stack<>(String::new)

One can use an ObjectOutputStream/ObjectInputStream to make a deep copy.
One would then not store an Object (a reference to changeable fields), but the serialized bytes in the stack.
On to it.
An ObjectOutputStream does a deep copy.

If you want to go with an interface, or you don't like Valentin's approach, you could do this:
interface Copiable<T> {
T deepCopy();
}
public class Stack<T extends Copiable<T>> {
...
}
and then implement the deepCopy method to objects that you put in your stack, i.e.
class A implements Copiable<A> {
#Override
public A deepCopy() {
// ... your copy code here
}
}
Stack<A> stack = new Stack<>();
etc.

Related

Is this stack or stack emulation?

package java.util;
public
class Stack<E> extends Vector<E> {
public Stack() {
}
public E push(E item) {
addElement(item);
return item;
}
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
private static final long serialVersionUID = 1224463164541339165L;
}
Above is the java source code for stack.
I realized that it is only emulating a stack and not a real one.So my questions are
Am I right in saying that this is just an imitation of Stack and not the real one?
If I can say the above and I want to build it from scratch,how would I do it?(arrays of fixed size or arraylist which in turn uses list(single/double linked)?)
There is no "real Stack", a stack is just an idea, a so-called abstract data type. It supports two operations, push and pop, and the order of elements is defined to be last-in first-out (LIFO). In addition to java.util.Stack (based on Vector, which is array-based), you also have java.util.LinkedList (a doubly-linked list), which also supports stack operations, so it's also a stack as much as the other one.. There are several other implementations, for example all implementations of java.util.Deque.
You can do it from scratch in a number of ways, each has their own trade-offs. Your question is not defined enough for a good answer.

Fundamental misunderstanding of objects and attributes in Java

I'm sitting on an assignment for university and I'm at a point, where I fear I haven't really understood something fundamental in the concecpt of Java or OOP altogether. I'll try to make it as short as possible (maybe it's sufficient to just look at the 3rd code segment, but I just wanted to make sure, I included enough detail). I am to write a little employee management. One class within this project is the employeeManagement itself and this class should possess a method for sorting employees by first letter via bubblesort.
I have written 3 classes for this: The first one is "Employee", which contains a name and an ID (a running number) , getter and setter methods and one method for checking whether the first letter of one employee is smaller (lower in the alphabet) than the other. It looks like this:
static boolean isSmaller(Employee source, Employee target) {
char[] sourceArray = new char[source.name.length()];
char[] targetArray = new char[target.name.length()];
sourceArray = source.name.toCharArray();
targetArray = target.name.toCharArray();
if(sourceArray[0] < targetArray[0])
return true;
else
return false;
}
I tested it and it seems to work for my case. Now there's another class called EmployeeList and it manages the employees via an array of employees ("Employee" objects). The size of this array is determined via constructor. My code looks like this:
public class EmployeeList {
/*attributes*/
private int size;
private Employee[] employeeArray;
/* constructor */
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
}
/* methods */
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
/* adds employee to end of the list. Returns false, if list is too small */
boolean add(Employee m) {
int id = m.getID();
if (id > employeeArray.length) {
return false;
} else {
employeeArray[id] = m;
return true;
}
}
/* returns employee at certain position */
Employee get(int index) {
return employeeArray[index];
}
/* Sets employee at certain position. Returns null, if position doesn't exist. Else returns old value. */
Employee set(int index, Employee m) {
if (employeeArray[index] == null) {
return null;
} else {
Employee before = employeeArray[index];
employeeArray[index] = m;
return before;
}
}
Now comes my real problem: In a third class called "employeeManagement" I am supposed to implement the sorting algorithm. The class looks like this:
public class EmployeeManagement {
private EmployeeList ml = new EmployeeList(3);
public boolean addEmployee(Employee e) {
return ml.add(e);
}
public void sortEmployee() {
System.out.println(ml.getSize()); // I wrote this for debugging, exactly here lies my problem
for (int n = ml.getSize(); n > 1; n--) {
for (int i = 0; i < n - 1; i++) {
if (Employee.isSmaller(ml.get(i), ml.get(i + 1)) == false) {
Employee old = ml.set(i, ml.get(i + 1));
ml.set(i+1, old);
}
}
}
}
The "println" before my comment returns "0" in console... I am expecting "3" as this is the size I gave the "EmployeeList" as parameter of the constructor within my "EmployeeManagement" class. Where is my mistake ? And how can I access the size of the object I created in the "EmployeeManagement" class (the "3") ? I'm really looking forward to your answers!
Thanks,
Phreneticus
You are not storing size in your constructor. Something like,
public EmployeeList(int size) {
this.employeeArray = new Employee[size];
this.size = size; // <-- add this.
}
Also, setSize isn't going to automatically copy (and grow) the array. You will need to copy the array, because Java arrays have a fixed length. Finally, you don't really need size here since employeeArray has a length.
The size variable you are calling is the class field. If you take a quick look at your code, the getter is getting the field (which is initialized as zero when created). The size you are using it. The good way of doing it would be to get the size of the array in the getter like this:
public int getSize() {
return employeeArray.length;
}
This would return the size of the array in the object.

How to use Comparable as a Generic parameter in a Class

I have a home work in a data structures course, the question is:
Implementation of doubly-linked list class.
the methods:
display()
length() or size()
insertSorted(Comparable)
insertToEnd(Comparable)
insertToHead(Comparable)
delete(Comparable)
boolean search(Comparable)
You must do this in JAVA
Create an application layer to test your class and its methods.
Compress all of your source files into a file and rename it as CS214HW1_first_lastName.zip Put your name in the filename. If needed, add a ReadMe.txt file for extra information such as compilation.
I implemented everything correctly and the code is working fine, but I used for example: insertSorted(int) instead of insertSorted(Comparable), because I didn't know how to do it.
I searched online, and read the JAVA documentation for (Comparable) but it is not enough :(
Can anybody help, please it is very important?
Here's some of my code, I can't write it all, cuz I don't want my friends to get the same code.
I will take zero if there is same code.
Code:
class DLL {
class Node {
Node next;
Node prev;
int data;
Node() {
next = null;
prev = null;
data = 0;
}
Node(int dt) {
next = null;
prev = null;
data = dt;
}
}
Node head;
void insertToHead(int dt) {
if (head == null) {
head = new Node(dt);
}
else {
head.prev = new Node(dt);
head.prev.next = head;
head = head.prev;
}
}
public static void main(String args[]) {
DLL dll = new DLL();
dll.insertToHead(1);
dll.insertToHead(2);
dll.insertToHead(3);
}
}
Please, somebody, tell me what to change in the beginning of the class.
are we gone use extends or implements Comparable<E> or what!
and what changes should i do the method insertToHead(Comparable)
what changes should i do to the main.
You would probably like to look into how generics work as well. The basic idea is that you would like to set up your class so that it will not know exactly the specific type of object but can be given some hint at the types of things it can expect of a declared generic type.
In your case, you would like to set up your list so that you can create linked lists of anything that can be compared. Java has a class for that which you have mention called Comparable<E> this tells Java that it will be able to call such methods as compareTo on the provided object.
More specifically to your closing questions:
Use the following style of class declaration MyClass<MyGenericType extends Comparable<MyGenericType>>. In your case DLL<E extends Comparable<E>>.
Switch the method arguments to accept E our declared generic type.
You should use the class Integer instead of the primitive type int, and change the creation of your list to DLL<Integer> dll = new DLL<Integer>().
Fully updated version of provided code:
public class DLL<E extends Comparable<E>> {
class Node {
Node next;
Node prev;
E data;
Node() {
next = null;
prev = null;
data = null;
}
Node(E dt) {
next = null;
prev = null;
data = dt;
}
}
Node head;
void insertToHead(E dt) {
if (head == null) {
head = new Node(dt);
}
else {
head.prev = new Node(dt);
head.prev.next = head;
head = head.prev;
}
}
public static void main(String args[]) {
DLL<Integer> dll = new DLL<Integer>();
dll.insertToHead(1);
dll.insertToHead(2);
dll.insertToHead(3);
}
}
This new implementation should provide a hint for how to proceed with some of the other homework tasks. For instance you can now compare objects just by their compareTo method which might useful for sorting hint hint.
That doc page gives a very good explanation for how to use this method. You should note that in their docs, they use a generic type called T instead of E, it really doesnt make a difference you can call it whatever you want provided it is unique to your program.
Edit:
An each hint in the sorting direction:
Ojbects which extend the Comparable class have a method which is called compareTo this method is set up so you can call:
object1.compareTo(object2);
this method returns an int which will be:
> 0 when object1 is greater than object2
= 0 when object1 is equal to object2
< 0 when object1 is less than object2
I don't want to give away too much as this is a homework assignment but here is my hint:
The way the above code sets up your classes, you would be able to tell the relationship between NodeA and NodeB by calling:
NodeA.data.compareTo(NodeB.data)
this will return an integer which gives your information according to the list above.
The <=,>=,== operators are likely found in the Integer class's compareTo method.
Something like:
public int compareTo(Object o) {
int otherNumber = ((Integer) o).intValue();
int thisNumber = this.intValue();
if (otherNumber > thisNumber) {
return 1;
} else if (otherNumber < thisNumber) {
return -1;
} else {
return 0;
}
}
but more likely they just do something like:
public int compareTo(Object o) {
return this.intValue() - o.intValue(); // possibly normalized to 1, -1, 0
}
See the Docs on Integer for more info on this.

Iterating through elements of a data structure instead of Collection

My problem is this: I have an iterator class which is supposed to iterate through elements in a given data structure, <E> let's say, but what I have managed to accomplish is that when I pass in the data structure it will iterate the data structure itself.
ie. DynamicIterator it = new DynamicIterator(da);
say da is an array the output will be [1,2,3,4,5,6] instead of 1,2,3,4,5,6
My issue is, more than anything, understanding the generally accepted practice for dealing with this more than the issue itself.
edit for code:
public class X<E>
{
private final E[] rray;
private int currentIndex = 0;
public X(E... a)
{
//if the incoming array is null, don't start
if(a == null)
{
System.out.println("Array is null");
System.exit(1);
}
//set the temp array (rray) to the incoming array (a)
this.rray = a;
}
//hasNext element?
public boolean hasNext()
{
return rray.length > currentIndex;
}
//next element (depends on hasNext())
public E next()
{
if (!hasNext())
{
System.out.println("Element doesn't exist, done");
System.exit(1);
}
return rray[currentIndex++];
}
//return array
public E[] access()
{
return rray;
}
}
You won't be able to do this with a completely generic parameter <E> - how would you iterate through a Throwable, for example? What your class X does at the moment is accept any number of objects in its constructor, and then simply returns each of those objects in turn.
If you restricted the bounds of the objects passed in to implement e.g. Iterable, then you can actually start to "look inside" them and return their contents:
public class X<E> {
private final Iterator<E> it;
public X(Iterable<E> a) {
it = a.iterator();
}
public boolean hasNext() {
return it.hasNext();
}
public E next() {
return it.next();
}
}
Although this doesn't really accomplish anything different to just using a.iterator() directly instead of an instance of X...

"Generic" solution for primitive array?

I have classes that for processing primitive array input: CharArrayExtractor for char[], ByteArrayExtractor for byte[], IntegerArrayExtractor for int[], ...
public void CharArrayExtractor {
public List<Record> extract(char[] source) {
List<Record> records = new ArrayList<Record>();
int recordStartFlagPos = -1;
int recordEndFlagPos = -1;
for (int i = 0; i < source.length; i++) {
if (source[i] == RECORD_START_FLAG) {
recordStartFlagPos = i;
} else if (source[i] == RECORD_END_FLAG) {
recordEndFlagPos = i;
}
if (recordStartFlagPos != -1 && recordEndFlagPos != -1) {
Record newRecord = makeRecord(source, recordStartFlagPos,
recordEndFlagPos);
records.add(newRecord);
recordStartFlagPos = -1;
recordEngFlagPos = -1;
}
}
}
}
public void ByteArrayExtractor {
public List<Record> extract(byte[] source) {
// filter and extract data from the array.
}
}
public void IntegerArrayExtractor {
public List<Record> extract(int[] source) {
// filter and extract data from the array.
}
}
The problem here is that the algorithm for extracting the data is the same, only the types of input are different. Everytime the algorithm changes, I have to change all of the extractor classes.
Is there a way to make extractor classes more "generics"?
Best regards.
EDIT: It seems that every suggestion so far is to use autoboxing to archive generic. But the number of elements of the array is often large, so I avoid using autoboxing.
I added more specific implementation of how the data is being extracted. Hope it will clarify something.
New Idea
Or a different approach is wrapping the primitive arrays and covering them with the methods you use for your algorithm.
public PrimitiveArrayWrapper {
private byte[] byteArray = null;
private int[] intArray = null;
...
public PrimitiveArrayWrapper(byte[] byteArray) {
this.byteArray = byteArray;
}
// other constructors
public String extractFoo1(String pattern) {
if(byteArray != null) {
// do action on byteArray
} else if(....)
...
}
}
public class AlgorithmExtractor {
public List<Record> do(PrimitiveArrayWrapper wrapper) {
String s= wrapper.extractFoo1("abcd");
...
}
}
This mainly depends if you have a lot of methods to call which you would have to cover. but at least you must not edit the algorithm more over the way how to access the primitive array. Furthermor you would also be able to use a different object inside the wrapper.
Old Idea
Either use generics or what i also think about is to have three methods which convert the primitive types into value types.
public void Extractor {
public List<Record> extract(byte[] data) {
InternalExtractor<Byte> ie = new InternalExtractor<Byte>();
return ie.internalExtract(ArrayUtils.toObject(data));
}
public List<Record> extract(int[] data) {
...
}
}
public void InternalExtractor<T> {
private List<Record> internalExtract(T[] data) {
// do the extraction
}
}
ArrayUtils is a helper class from commons lang from Apache.
I'm not sure how your filter will work as it will not know anything about the type the array contains.
Using reflection you can possibly do what you want but you will loose compile time type safety.
The java.lang.reflect.Array class provides functions for manipulating an array without knowing its type.
The Array.get() function will return the value at the requested index of the array and if it is a primitive wrap it in its corresponding Object type. The downside is you have to change your method signature to accept Object instead of specific array types which means the compiler can no longer check the input parameters for you.
Your code would become:
public class ArrayExtractor {
public List<Record> extract(Object array) {
// filter and extract data from the array.
int length = Array.getLength(array);
for (int index = 0; index < length; index++) {
Object value = Array.get(array, index);
// somehow filter using value here
}
}
}
Personally I would prefer having type safety over using reflection even if it is a little more verbose.
interface Source
int length();
int get(int index);
extract(final byte[] source)
extract( new Source(){
int length(){ return source.length; }
int get(int i){ return source[i]; }
} );
// common algorithm
extract(Source source)
for(int i=0; i<source.lenth(); i++)
int data = source.get(i);
...
Instead of passing each type, pass the class of the type as the below:
public List<Record> extract(Class srcClass) {
if (int[].class.equals(srcClass) {
// filter and extract data from the int[] array.
}
else if (..) // do same for other types
}
public void Extractor<T> {
public List<Record> extract(T[] source) {
// filter and extract data from the array.
}
}
http://download.oracle.com/javase/tutorial/extra/generics/methods.html
You could do something like this.
public class ArrayExtractor<T>
{
public List<T> extract (T[] source)
{
// filter and extract data from the array.
}
}
You would have a generic Extractor class and your implementation would be the same.
You cant use Javas generics because of primitive type source, your best bet is to try some java reflection api to analyze the incoming source and invoke the extractors on your own.
I think is is possible to do create a method like this:
public List<Record> extract(List<Number> source) {
// filter and extract data from the array.
}
And use Arrays.asList(yourPrimaryArrayType), to make it compatible.
After my tests and the comment of Sean Patrick Floyd, you will be able to do this by create once some helper methods, for converting primitive arrays to lists:
public static void main(String[] args)
{
int[] i = {1,2,3};
System.out.println(extract(asPrimitiveList(i)));
}
public static List<Object> extract(List<Number> source) {
List<Object> l = new ArrayList<Object>();
l.add(0);
for (Number n : source)
{
// I know this line is rubbish :D
l.set(0, ((Number) l.get(0)).doubleValue() + n.doubleValue());
}
return l;
}
private static List<Number> asPrimitiveList(int[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
private static List<Number> asPrimitiveList(byte[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
private static List<Number> asPrimitiveList(char[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
No, it is never possible.
For example take a look at documentation of ArrayUtils.copyOf(byte[] original, int newLength). And there exists other methods for remaining primitives. This is kind of same behavior (literally) you wanted. If it was possible similar code should exists somewhere else.
Additionally we can discuss more about how generic works, but it would be another issue, i guess.
Depends on what you're trying to achieve. But maybe you can work with primitive wrappers instead? Then you could write generic Extractor<? extends Number> (here Number is the abstract class extended by all primitive wrappers).
Yes, you should be able to use generics:
interface Extractor<T, R> {
public List<R> extract(T source);
}
class BaseExtractor<T> implements Extractor<T, Record>
{
public List<Record> extract(T source)
{
//do your thing
}
}
Here, you would have to assume that T is a primitive array, as you cannot use primitives in generic definitions.
Or else, you could use the wrapper Objects and do it this way:
interface Extractor<T, R> {
public List<R> extract(T[] source);
}
class BaseExtractor<T> implements Extractor<T, Record>
{
public List<Record> extract(T[] source)
{
//do your thing
}
}
In this case, your generic T can be Byte, Integer, etc.

Categories

Resources