Copy Constructor for a String Array in Java - java

So I'm currently working on a project that is recreating methods for Array String Lists and Linked String Lists. There is a StringList interface, that both ArrayStringList and LinkedStringList implement. We are not allowed to see the source code for the interface - only the API documentation. For each class, we have to create a default constructor and copy constructor for both classes. I've ran tests, and the default constructors both pass but the ArrayStringList copy constructor does not work and has been throwing the error message of "null" or "-1". I am pretty new to inheritance and interfaces, and I think the object parameters vs string array data types are throwing me off a bit.
Here is the code I have so far, and the methods used in the constructor:
My Copy Constructor:
private String[] stringArray;
private int size;
public ArrayStringList(StringList sl) {
size = sl.size();
ArrayStringList asl = new ArrayStringList();
for(int i = 0; i < size-1; i++) {
if(sl.get(i) != null) {
asl.set(i,sl.get(i).toString());
} //if
} // for
} // copy constructor
Size Method:
public int size() {
return stringArray.length;
} // size
Get Method:
public String get(int index) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException("out of bounds");
} else {
return stringArray[index];
}
} //get
Set Method:
public String set(int index, String s) {
String old = stringArray[index];
stringArray[index] = s;
return old;
} // set
In the project, the description of the copy constructor was as follows:
The implementing class must explicitly define a copy constructor. The copy constructor should take exactly one parameter of the interface type StringList. It should make the newly constructed list object a deep copy of the list referred to by the constructor's parameter. Therefore, the initial size and string elements of the new list object will be the same as the other list. To be clear, the other list can be an object of any implementation of the StringList interface. No other assumptions about the type of the object should be made.

public class ArrayStringList implements StringList {
private static final int INITIAL_CAPACITY = 10;
private String[] stringArray;
private int size;
public ArrayStringList(StringList sl) {
stringArray = sl.toArray();
size = stringArray.length;
}
public ArrayStringList() {
stringArray = new String[INITIAL_CAPACITY];
size = 0;
}
// TODO: Extract 'if-cascade' to an validate(..) method
#Override
public String set(int index, String s) {
if (index >= size) {
throw new IndexOutOfBoundsException("")
} else if (s == null) {
throw new NullPointerException("the specified string is null");
} else if (s.isEmpty()) {
throw new IllegalArgumentException("specified string is empty");
}
String old = stringArray[index];
stringArray[index] = s;
return old;
}
// TODO: Check if posible to extend the stringArray
#Override
public boolean add(String s) {
if (s == null) {
throw new NullPointerException("the specified string is null");
} else if (s.isEmpty()) {
throw new IllegalArgumentException("specified string is empty");
}
if (size == stringArray.length) {
int newListCapacity = stringArray.length * 2;
stringArray = Arrays.copyOf(stringArray, newListCapacity);
}
stringArray[++size] = s;
return true;
}
// TODO: implement other methods ...
}
Keep in mind that this implementation is still buggy, but you can use it as a starting point

public void ArrayStringList(StringList sl) {
size = sl.size();
ArrayStringList asl = new ArrayStringList();
for(int i = 0; i < size; i++) {
if(sl.get(i) != null) {
String s = asl.set(i,sl.get(i).toString());
System.out.println(s);
} //if
} // for
}
Change set method like below. And call it by the help of class object. it will set value in global static list.
//Change set method like this
public String set(int index, String s) {
stringArray[index] = s;
return stringArray[index];
}

I would initialise the internal array to the value of size and also make use of the fact that the String class also has a copy-constructor
public ArrayStringList(StringList sl) {
this.size = sl.size();
this.stringArray = new String[size];
for(int j = 0; j < size; j++) {
this.stringArray[j] = new String(sl.get(i));
}
}

Related

How to I add a single object into an array

For my project I need to add a Creature into an array of creatures thats created in a room
public class Room
{
String name;
String description;
String state;
Creature [] creatures = new Creature[10];
public Room(String roomName)
{
name = roomName;
}
public String toString()
{
String retValue = "";
for (int i = 0; i < creatures.length; i++) {
retValue = retValue + creatures[i].toString();
}
return retValue;
}
public void addCreature(String creatureName)
{
for (int i = 0; i < creatures.length; i++)
{
if(creatures[i] == null)
{
creatures[i] = new Creature(creatureName);
}
}
}
}
when I do this, it overwrites the entire array, what can I do to add a single creature to the array?
Use break statement.
if(creatures[i] == null)
{
creatures[i] = new Creature(creatureName);
break;
}
Arrays have only a fixed size. When you write new Creatures[10], it means that your creatures array has at maximum 10 elements inside of it.
You can add items in two different ways:
You can copy the array and make it bigger, and then add the item
You can use ArrayList, which is a class which automatically does #1 for you
I would recommend ArrayList:
ArrayList:
List<Creature> creatures = new ArrayList<>();
public void addCreature(String creatureName) {
creatures.add(new Creature(creatureName));
}
Seems you miss one condition in if clause. I guess it should be
if(current == null || current.getCreatureName() == null) {
creatures[i] = new Creature(creatureName);
}

Why am I getting a NullPointerException with this ArrayList? [duplicate]

This question already has answers here:
java "void" and "non void" constructor
(5 answers)
Closed 5 years ago.
When ever I add an object to this ArrayList, my resize method, gives me a NullPointerException. The list is initialized with a size of 1, and the first element is added to possition 0 in the array.
Here is my arrayList AKA DynamicArray
//Implementation of a dynamic array
// Add remove methods
public class DynamicArray {
private Object[] data;
private int size;
public void DynamicArray(){
data = new Object[1];
size = 0;
}
public int size(){return size;}
public Object get(int index){return data[index];};
private void resizeIfFull()
{
if (size < data.length){
return;
} else {
Object[] bigger = new Object[2 * data.length];
for (int i = 0; i < data.length; i++){
bigger[i] = data[i];
data = bigger;
}
}
}
public void add(Object obj){
resizeIfFull();
data[size] = obj;
size++;
}
public void add(int index, Object obj){
resizeIfFull();
for(int i = size - 1; i >= index; i--){
data[i+1] = data[i];
}
data[index] = obj;
size++;
}
public void remove(int index){
for(int i = index; i < size; i++){
data[i] = data[i+1];
}
size--;
}
}
Here is my testing class.
public class AlgorTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
DynamicArray dynam = new DynamicArray();
System.out.println(dynam.size());
dynam.add("first");
}
}
Here is my output from the testing class.
0
Exception in thread "main" java.lang.NullPointerException
at DynamicArray.resizeIfFull(DynamicArray.java:20)
at DynamicArray.add(DynamicArray.java:38)
at AlgorTest.main(AlgorTest.java:8)
Confusingly, this isn't a constructor:
public void DynamicArray(){
data = new Object[1];
size = 0;
}
It's a function called DynamicArray (very confusing, I know).
Without the class having a constructor, data remains null and leads to an NPE when you try to access the array.
Drop the void keyword to turn the function into a constructor (which would then initialize data etc):
public DynamicArray(){
data = new Object[1];
size = 0;
}
constructor doesn't have return value , remove return type from constructor (void)
public DynamicArray(){
data = new Object[1];
size = 0;
}
in your case when you initialize object from DynamicArray class then default constructor will execute which does nothing

How do I output a variable changed in a void method in Java

According to an exercise for school I am supposed to println the int variable 'aantalWoorden' and the Arraylist 'woorden' after they are updated in the 'woordenNaarLijst' method. But whenever I do that, I get the values from the default constructor (Because they are updated inside a method). The method is supposed to be void, so I can't return the values. How do I get the values of the int and array as they are defined in the 'woordenNaarLijst' method without changing the method itself.
I am sorry if this is a easy question or if I am doing something wrong, but I am relatively new to programming.
public class AnalyseZin {
private String zin;
int aantalWoorden;
int i1 = 0, i2 = 0;
private ArrayList<String> woorden;
public AnalyseZin() {
woorden = new ArrayList<>();
aantalWoorden = 0;
}
public int getIndex(int i) {
char c;
for (; i < zin.length(); i++) {
c = zin.charAt(i);
if (c == '\n' || c == '.' || c == ',' || c == ' ')
return i;
}
return i;
}
public String getWoord() {
i2 = getIndex(i1);
StringBuilder sb = new StringBuilder();
for (; i1 < i2; i1++) {
sb.append(zin.charAt(i1));
}
return sb.toString();
}
public void woordenNaarLijst() {
String s;
while (true) {
s = getWoord();
if (s.length()==0) break;
woorden.add(s);
aantalWoorden++;
}
}
}
I left out irrelevant pieces of code, the code does work at my end.
Maybe if you just want to get the values of aantalWoorden and woorden regardless if it has been properly updated or not, you might want to create getters for those.
Example:
// Additional getter methods in AnalyseZin
public int getAantalWoorden(){
return aantalWoorden;
}
public ArrayList<String> getWoorden(){
return woorden;
}
So if you create the AnalyseZin object you can do this:
// create variables for the container of values from the AnalyseZin
int newIntVal = 0;
ArrayList<String> newListVal = new ArrayList<String>();
// create instance of the object
AnalyseZin test = new AnalyseZin();
// call woordenNaarLijst method to update the woorden and aantalWoorden
test.woordenNaarLijst();
// pass values from AnalyseZin
newIntVal = test.getAantalWoorden
newListVal = test.getWoorden();
// print out int values
System.out.println("new int value = " + Integer.toString(newIntVal));
// print out list contents
for (String item : newListVal){
System.out.println("item from list = " + item);
}
Hope this helps.

how to iterate through an array list of class type

I have two classes A and B. I want to access an array list in A from B. The array list is of class C type, which stores objects(packets). I would like to know if there is any way to iterate through the list and get specific data from each packet.
public class PcapStream
{
PcapParser objPcapParser = new PcapParser();
PcapDef numPackets = new PcapDef();
int listSize = numPackets.getMaxPackets();
public void findStream()
{
final ListIterator<PcapDef> packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(final int i=0; i<=listSize;i++)
{
I started off with something like this. Not sure how it works. Class B is PcapStream, Class A is PcapParser, Class C is PcapDef
ListIterator packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(int i=0; i<listSize; i++ )
{
PcapDef packet1 = (PcapDef) packetIterator.next();
PcapDef packet2 = packetIterator; //here I would like to get the 2nd object from the list, not sure how to get that at this point.
}
}
public int compare(final PcapDef packet1, final PcapDef packet2)
{
return 0;
}
I'm still working on it. At this point this is what I have
public void findStream()
{
try
{
for(int i=0;i<listSize;i++)
{
final List <PcapDef> list = new ArrayList<PcapDef>();
final PcapDef packet1 = objPcapParser.packet_list.get(i);
checkPackets(packet1, list, i);
}
}
catch(final IndexOutOfBoundsException e)
{
System.out.println("Exception : " + e);
}
final Set packetSet = Stream.entrySet();
final Iterator setIterator = packetSet.iterator();
while(setIterator.hasNext())
{
final Map.Entry packetEntry = (Map.Entry) setIterator.next();
System.out.print(packetEntry.getKey() + ": ");
System.out.println(packetEntry.getValue());
}
}
private void checkPackets(final PcapDef packet1, final List<PcapDef> list, final int i)
{
for(int j=1;j<listSize && j!=i;j++)
{
final PcapDef packet2 = objPcapParser.packet_list.get(j);
final int value = compare(packet1,packet2);
if(value == 0)
{
list.add(packet1);
list.add(packet2);
checkPackets(packet2, list, i);
}
else
{
Stream.put(i,list); //add list to hashmap
}
}
}
#Override
public int compare(final PcapDef packet1, final PcapDef packet2)
{
final String header1 = packet1.getHeader();
final String header2 = packet2.getHeader();
final String src_port1 = packet1.getSrc_port();
final String dst_port2 = packet2.getDst_port();
final String src_port2 = packet2.getSrc_port();
final String dst_port1 = packet1.getDst_port();
System.out.println(header1 + header2);
int flag = 1;
try{
if(header1.equalsIgnoreCase(header2))
{
if((src_port1.substring(10).equalsIgnoreCase(dst_port2.substring(10))) && (src_port2.substring(10).equalsIgnoreCase(dst_port1.substring(10)) )
{
flag = 0;
return flag;
}
}
}
#Andy This is what I wrote so far. Problems I'm facing: Duplicates are being generated and hashmap entries are not continuous, I mean like index 0,1,2.. instead few locations are empty. Due to this if I give very large files as input to my program it is throwing me an indexoutofboundsexception. I'm a beginner and trying my best. Kindly, help.
You can use the Iterator.next() method to get the next list member. Each call to next() advances to the next list member.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
...
}
EDIT:
And you can use the Iterator.get(int) method to get a list member by index.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
for(int i=0; i<listSize; i++ )
{
PcapDef packet2 = objPcapParser.packet_list.get( i )
...
}
}

Null pointer exception for Array of Objects

I am new to using arrays of objects but can't figure out what I am doing wrong and why I keep getting a Null pointer exception. I am trying to create an Theatre class with an array of spotlight objects that are either set to on or off. But - whenever I call on this array I get a null pointer exception.
package theatreLights;
public class TheatreSpotlightApp {
public static void main(String[] args) {
Theatre theTheatre = new Theatre(8);
System.out.println("element 5 " + theTheatre.arrayOfSpotlights[5].toString());
}
}
package theatreLights;
public class Theatre {
spotlight[] arrayOfSpotlights;
public Theatre(int N){
arrayOfSpotlights = new spotlight[N];
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i].turnOn();
}
}
}
package theatreLights;
public class spotlight {
int state;
public spotlight(){
state = 0;
}
public void turnOn(){
state = 1;
}
void turnOff(){
state = 0;
}
public String toString(){
String stringState = "";
if(state == 0){
stringState = "is off";
}
else if(state==1){
stringState = "is on";
}
return stringState;
}
}
I must be doing something basic wrong in creating the array but can't figure it out.
replace
arrayOfSpotlights[i].turnOn();
with
arrayOfSpotLights[i] = new Spotlight();
arrayOfSpotlights[i].turnOn();
The line
arrayOfSpotlights = new spotlight[N];
will create an array of spotlights. It will however not populate this array with spotlights.
When you do "arrayOfSpotlights = new spotlight[N];" you init an array of length N, what you need to do is also init each object in it:
for i=0; i<N; i++
arrayOfSpotlights[i] = new spotlight();
arrayOfSpotlights[i].turnOn();
Hope I'm correct :)
You are not creating an spotlight objects.
arrayOfSpotlights = new spotlight[N];
This just creates an array of references to spotlights, not the objects which are referenced.
The simple solution is
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i] = new spotlight();
arrayOfSpotlights[i].turnOn();
}
BTW You should use TitleCase for class names.
You could write your class like this, without using cryptic code like 0 and 1
public class Spotlight {
private String state;
public Spotlight() {
turnOff();
}
public void turnOn() {
state = "on";
}
void turnOff() {
state = "off";
}
public String toString() {
return "is " + state;
}
}
You declared the array arrayOfSpotlights, but didn't initialize the members of the array (so they are null - and you get the exception).
Change it to:
public class Theatre {
spotlight[] arrayOfSpotlights;
public Theatre(int N){
arrayOfSpotlights = new spotlight[N];
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i]=new spotlight();
arrayOfSpotlights[i].turnOn();
}
}
}
and it should work.

Categories