Reputation: 31272
I have the following ArrayIntList class with constructors defined as below. In the last constructor, I want to have boolean, which if true, instantiates a new object with that particular element in it. If set to false, it should just instantiate a new object with that many capacity. kindly look at the client code for what I mean here. it works when boolean is true.
Class FILE:
public class ArrayIntList {
private int[] elementData; // list of integers
private int size; // current number of elements in the list
public static final int DEFAULT_CAPACITY = 100;
// post: constructs an empty list of default capacity
public ArrayIntList() {
this(DEFAULT_CAPACITY);
}
// pre : capacity >= 0 (throws IllegalArgumentException if not)
// post: constructs an empty list with the given capacity
public ArrayIntList(int capacity) {
if (capacity < 0) {
throw new IllegalArgumentException("capacity: " + capacity);
}
elementData = new int[capacity];
size = 0;
}
//takes input list and adds to arrayIntList
public ArrayIntList(int[] elements) {
this(Math.max(DEFAULT_CAPACITY,elements.length*2));
for (int n: elements){
this.add(n);
}
}
//creates an arrayIntlist with data of element
public ArrayIntList(int element,boolean notCapacity) {
this();
if (notCapacity) {
add(element);
}
//returns the totalCapacity NOT SIZE
public int getCapacity() {
return elementData.length;
}
}
Client code:
public class ArrayIntListExample {
public static void main(String[] args) {
// Create a new list and add some things to it.
ArrayIntList list = new ArrayIntList();
//*** here is my question about ****//
ArrayIntList list1 = new ArrayIntList(2, false);//should give [] with capacity of two
ArrayIntList list2 = new ArrayIntList(2, true);//should give [2]
//*** ****************************** ****//
int[] array={2,3,4,5};
ArrayIntList list3 = new ArrayIntList(array);
list.add(12);
list.add(3);
list.add(3);
System.out.println("list = " + list);
System.out.println("list1 = " + list1);
System.out.println("list2 = " + list2);
System.out.println("list2 = " + list3);
System.out.println("capacity of list1" + list1.getCapacity());//prints 100 but it must be 2
}
}
Upvotes: 0
Views: 776
Reputation: 95588
To want it to behave the way you want, I imagine you want to pass element
to the constructor with the lone int
parameter:
public ArrayIntList(int element, boolean notCapacity) {
this(element);
if (notCapacity) {
add(element);
}
}
Previously you were simply calling this()
, which initializes the array with the default capacity. If you step through your code manually or with a debugger, you can see this happening.
There are other problems with your design, however. Aside from an unwieldy and confusing interface/API (through your constructors), there is also a difference between the capacity of your array (i.e., the total number of elements it can hold) and its size (i.e., the number of elements in the array currently).
EDIT
One of the reasons why your API is confusing is that you have the following scenario:
-------------------------------------------------------------------
Constructor | int | boolean | Behavior
-----------------------+-----+---------+---------------------------
(element) | 2 | x | Array with capacity 2
(element, notCapacity) | 2 | true | Array with one element (2)
(element, notCapacity) | 2 | false | Array with capacity 2
-----------------------+-----+---------+---------------------------
boolean
argument that is given a negative name. It's easier to figure out the meaning of "capacity is false" than "notCapacity is false".notCapacity
serves is to distinguish the two behaviors that you want (initializing with capacity vs. initializing with one element of arbitrary value).element
has two, very different meanings: capacity vs. single element to be added to the array.false
to true
is enough to invoke wildly-different behavior from the constructor.new ArrayIntList(5, true)
, is the intent obvious?Upvotes: 3
Reputation: 18257
Lets look at your constructor:
public ArrayIntList(int element,boolean notCapacity) {
this();
if (notCapacity) {
add(element);
}
}
Now lets look at this line:
this();
This line will call your constructor with no arguments. That constructor looks like this:
public ArrayIntList() {
this(DEFAULT_CAPACITY);
}
So this will call the constructor which takes a capacity and it will pass DEFAULT_CAPACITY to it. So adding some comments to the original:
public ArrayIntList(int element,boolean notCapacity) {
this(); // initializes this object with a capacity of 100 and no elements
if (notCapacity) {
add(element); // if notCapacity is true, add the element
}
}
As you can see, nowhere do you actually use the "element" variable if notCapacity is false (meaning it should be the capacity).
A very simple fix for this could be:
public ArrayIntList(int element,boolean notCapacity) {
this(notCapacity ? DEFAULT_CAPACITY : element);
if (notCapacity) {
add(element);
}
}
However, I think a better design would be to not have this constructor at all and instead provide the following static methods:
public static ArrayIntList createWithElement(int element) {
ArrayIntList ret = new ArrayIntList();
ret.add(element);
return ret;
}
Then the caller has a clean and clear method to call to create a list with 1 element.
Upvotes: 2
Reputation: 906
If you follow through the code it is clear why the behavior is happening.
public ArrayIntList(int element,boolean notCapacity) {
this();
if (notCapacity) {
add(element);
}
}
This method will create a new Array of DEFAULT_CAPACITY
and if its false it simply finishes the method and returns without anything else done.
The easiest solution would simply to add an else statement like this:
public ArrayIntList(int element,boolean notCapacity) {
this();
if (notCapacity) {
add(element);
} else {
elementData = new int[element];
}
}
Although, I would strongly suggest you rethink your class structure.
Upvotes: 0
Reputation: 2066
This should work, but I think your API is confusing..
public ArrayIntList(int element,boolean startElement) {
this(startElement ? 1 : element);
if (startElement) {
add(element);
}
}
I think you should remove this constructor and instead let users do new ArrayIntList(new int[] { 2 })
if they want a list with a specific element in.
Upvotes: 0