import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; /** * This Java Collection is able to write any kind of Object into a Array with an * unlimited capacity. It does not matter what type the Object is! * * @author Stefan Willam * @version 1.0 * */ public class HomeworkCollection implements Collection { /* i am using a array with the size 5 at the beginning that is extendable */ private T[] arrayForObjects = (T[]) (new Object[5]); private int arrayIndex; private int newIndex; private int iteratorIndex; // -- temp variables should not be attributes. They should be local whenever // needed // -> changed it @Override /* * the method add is adding an object to an array and returns true if it is * possible to add the object the add method is supporting a limitless * amount of new objects each each time an object is added it is extended by * one field - it is also possible to add more than one field - if only one * field is added, it is not so performant * * @param add any kind of object * * @return returns true when successfully added */ public boolean add(T arg0) { if (arrayIndex == arrayForObjects.length) { T[] temp = (T[]) (new Object[5]); temp = arrayForObjects; newIndex = arrayIndex + 1; arrayForObjects = (T[]) (new Object[newIndex]); /*- vl: this is wrong! Now if there is another thread using this * collection, then it migigth get null items from array. * First create the temp, then copy to temp and tehn change the real to * temp. Then tehre is no change to get wrong data * *-sw: created now a global temp[] variable * */ // -- I did no meen this. I meen that you create first the temp // array (local, NEVER GLOBAL) // copy the items there and then change the arrayForObjects to point // there // -> no global variable temp anymore for (int i = 0; i < arrayIndex; i++) { arrayForObjects[i] = temp[i]; } } arrayForObjects[arrayIndex] = arg0; arrayIndex++; return true; } @Override /* * the method addAll is adding a all elements of a collection to the array * and returns true if it is possible * * @param collection of objects * * @return returns true when successfully added */ public boolean addAll(Collection arg0) { boolean returnValue = true; boolean[] addAll = new boolean[arg0.size()]; int addAllCount = 0; for (T arg0Item : arg0) { if (add(arg0Item)) { addAll[addAllCount] = true; } else { addAll[addAllCount] = false; } addAllCount++; } for (int i = 0; i < arg0.size(); i++) { if (addAll[i] = false) returnValue = false; } return returnValue; } /* * - vl. Is it really so that even one add is ok? or should it be so that it * returns false if not all items is added? * * -sw. else with returning value false implemented */ // -- Now it returns true if f.ex just the last item is successfully added. // Is that the meaning? // -> it is complicated, but it works now // And now it is made too complicated. Now extra array is needed @Override /* * the method clear is deleting all elements by setting all elements null * and setting back the arrayIndex to 0 */ public void clear() { for (int i = 0; i < arrayIndex; i++) { arrayForObjects[i] = null; } arrayIndex = 0; } @Override /* * the method contains is going through every element and compares if it is * equals it returns true * * @param object to be checked * * @return returns true when the object is found */ public boolean contains(Object arg0) { for (int i = 0; i < arrayIndex; i++) { if ((arrayForObjects[i] == arg0)) return true; } return false; } @Override /* * the method containsAll is going trough every element and compares if all * elements are equal it returns true, if one is not equal it returns false * * @param collection of objects * * @return returns true when all objects from the collection are found */ public boolean containsAll(Collection arg0) { boolean returnValue = true; boolean[] containsAll = new boolean[arg0.size()]; int containsAllCount = 0; for (Object arg0Item : arg0) { if (contains(arg0Item)) { containsAll[containsAllCount] = true; } else { containsAll[containsAllCount] = false; } containsAllCount++; } for (int i = 0; i < arg0.size(); i++) { if (containsAll[i] = false) returnValue = false; } return returnValue; /* * - vl: i think this return wrong. Now it is enough that one item from * arg0 is found! * * -sw: implemented else that returns false if not all are containing */ // -- Same problem. if just last item is found, return true // -> solved it like above } @Override public boolean isEmpty() { /* * the method isEmpty is returning true if every element of the array is * null otherwise false * * @return returns true when the array is empty */ if (size() == 0) { return true; // - VL: return true, then no else needed } else { return false; } /* * - VL: but is it really so that array full on null's is empty???? Are * you sure just return size() == 0 is not enough? * * -sw: i looked in the Java Api and there stands: * "Returns true if this collection contains no elements." no elements * means to me, that it can be null, but if you like it, I change it -> * boolean variable "isEmpty" is then not needed */ // -- no items is that the count of items is 0. Array can contain // null's. It // is important value and does not mean empty array. It means array full // of null's. // So only the size matters. // -> ok changed it } @Override public Iterator iterator() { return new HomeworkIterator(); } @Override /* * the method remove has to look if the element is equal and if it is true * it is set to null, if it is removed it returns true otherwise false - the * position is now null and it is possible to address another element to * this position * * @param object to be removed * * @return returns true if the object is removed */ public boolean remove(Object arg0) { int position = 0; boolean remove = false; if (contains(arg0)) { for (int i = 0; i < arrayIndex; i++) { if (arrayForObjects[i] == arg0) { arrayForObjects[i] = null; remove = true; } } } return remove; } /*- VL: This is far far too complex to do a simple job. * There is no need for news no need for many loops inside... * * -sw: see comments within the method * i agree on it, that it is looking complicated, but I think it's ok * */ /*-- it might work, but it is totally possible to do with just one loop I call this kind of programing as arrowhead programming and it is not tolerated. No one can follow this. The complexity of you alghorithm is O(n4) as it is possible to do withs just O(n). So with 1000 item my version makes x*1000 operations and your one will make 1000*1000*1000*1000*x operations (x is some constant). -> now I really did only remove the required object by setting it to null */ @Override /* * the method removeAll is going trough every element and compares if all * elements are equal, if all elements are equal it removes them and returns * true, if they are not equal it returns false * * @param collection of objects * * @return returns true if all objects are removed */ public boolean removeAll(Collection arg0) { int i = 0; boolean removeAll = false; for (Object arg0Item : arg0) { for (int j = 0; j < arrayForObjects.length; j++) { if (arrayForObjects[i] == arg0Item) { remove(arrayForObjects[i]); removeAll = true; } } } return removeAll; } /* * - why not to do all in just one loop? * * -sw: because I first check if all elements are within the array and only * then I start removing them */ /*-- But if even just on item is in array you need to remove it and unnessesry loop all others. If you just start removinf, the remove iterates items and does nothing if nothing is to remove. Even in case of O(n) like I suggest. -> */ @Override /* * the retainAll method removes all elements that are not part of the arg0 * collection - this is done by simple overwriting the array * * @param collection of objects * * @return returns true if all objects are added */ public boolean retainAll(Collection arg0) { boolean retainAll = false; for (int j = 0; j < arrayIndex; j++) { if (!arg0.contains(arrayForObjects[j])) { remove(arrayForObjects[j]); retainAll = true; } /* * - VL: this is wrong. It should not add ALL the elements from arg0 * It just should remove those that are not in arg0. it is different * thing. * * -sw: changed this now */ /* * --- should it be arg0Item??? * * I think return value is wrong. Now it allways returns true. * * ->changed it */ } return retainAll; } @Override /* * the method size is returning the length of the array * * @return returns the size of the array */ public int size() { return arrayIndex; } @Override /* * the toArray method returns an array with all elements of the original * array * * @return returns an array with all elements of the original array */ public Object[] toArray() { Object[] newArrayForObjects = new Object[arrayIndex]; for (int i = 0; i < arrayIndex; i++) newArrayForObjects[i] = arrayForObjects[i]; return newArrayForObjects; } @SuppressWarnings("unchecked") @Override /* * this method is returning an array with all elements, arg0 is the target * container, if the size is correct, otherwise a new array is generate with * the runtype a * * @return returns an array with all elements if the size is correct */ public T[] toArray(T[] arg0) { if (arg0.length >= arrayIndex) { for (int i = 0; i < arg0.length; i++) { arg0[i] = (T) arrayForObjects[i]; // - VL: no need for typecast! // - SW: "Type mismatch: cannot convert from T to T" so I have // to convert it } return arg0; } return arg0; } class HomeworkIterator implements Iterator { // int iteratorIndex = 0; @Override public boolean hasNext() { if (arrayForObjects.length > iteratorIndex) { return true; } return false; } @Override public T next() { if (arrayForObjects.length == iteratorIndex) { throw new NoSuchElementException(); } iteratorIndex++; return (T) arrayForObjects[iteratorIndex - 1]; } @Override public void remove() { // not implemented method throw new UnsupportedOperationException(); } } }