Why isn't my toString method working in Java? - java

I'm in the process of writing a news feed program, and I'm trying to check if items are being added to the list array properly. In my test harness, I try to print the contents of the array after adding a made up item, but when I run the program, nothing is displayed. Is there a problem with my toString method (or otherwise)? Thanks for any help.
public class Feed {
private final int DEFAULT_MAX_ITEMS = 10; // default size of array
/* Attribute declarations */
private String name; // the name of the feed
private String[] list; // the array of items
private int size; // the amount of items in the feed
/**
* Constructor
*/
public Feed(String name){
list = new String[DEFAULT_MAX_ITEMS];
size = 0;
}
/**
* add method adds an item to the list
* #param item
*/
public void add(String item){
item = new String();
// add it to the array of items
// if array is not big enough, double its capacity automatically
if (size == list.length)
expandCapacity();
// add reference to item at first free spot in array
list[size] = item;
size++;
}
/**
* expandCapacity method is a helper method
* that creates a new array to store items with twice the capacity
* of the existing one
*/
private void expandCapacity(){
String[] largerList = new String[list.length * 2];
for (int i = 0; i < list.length; i++)
largerList[i] = list[i];
list = largerList;
}
/**
* toString method returns a string representation of all items in the list
* #return
*/
public String toString(){
String s = "";
for (int i = 0; i < size; i++){
s = s + list[i].toString()+ "\n";
}
return s;
}
/**
* test harness
*/
public static void main(String args[]) {
Feed testFeed = new Feed("test");
testFeed.add("blah blah blah");
System.out.println(testFeed.toString());
}
}

There are multiple problems here. For starters, I'd suggest:
1) Lose the "size" member variable
2) Substitute ArrayList<String> list for member variable "String[] list"
3) Use list.size() instead of a separate "size" variable
4) You can lose (or simplify) your "add()" method, too. Just use list.add() instead.
5) Step through the debugger. Verify "list" gets added to as you expect, when you expect.
FINALLY
6) Step through the debugger for "toString()". Make sure "list" is has the size and contents you expect.
'Hope that helps...

Related

Algorithm on an ordered collection of strings

I have an assessment to do and I'm not good at programming. I can search for the algorithms and see how they are done, but in my case I have ordered collection of strings and somehow I have to use the get method.
I have these two classes that must not be changed:
public class SearchTest {
/**
* Test program for the Search class.
* Put whatever tests you like in the body of the method.
* #param args the command line arguments
* #throws java.io.IOException of error reading the input
*/
public static void main(String[] args) throws IOException {
// Don't change this line
final Search search = new Search();
// You can set this to any of the text files in the data folder
final FileStrings strings = new FileStrings("data/small.txt");
// add your tests here
System.out.println(search.longestWord(strings));
}
}
and
public class FileStrings implements StringList {
/** Underlying list of elements */
private final ArrayList<String> elements;
/** Number of calls to get() since the last call to resetCount() */
private int count;
/**
* Create a list containing the lines of a text file.
* #param fileName name of a text file of strings, in order
* #throws java.io.IOException on input error
*/
public FileStrings(String fileName) throws IOException {
elements = new ArrayList<>();
try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = input.readLine()) != null) {
elements.add(line);
}
}
count = 0;
}
/**
* Returns the number of elements in this list.
* This method takes constant time.
* #return the number of elements in this list
*/
#Override
public int size() {
return elements.size();
}
/**
* Returns the element at the specified position in this list.
* This method takes constant time.
* #param i position in the list, between 0 and size()-1
* #return the element at the position i
*/
#Override
public String get(int i) {
count++;
return elements.get(i);
}
/**
* Reset the count field.
*/
public void resetCount() {
count = 0;
}
/**
* Getter for count.
* #return number of calls to get() since the last resetCount()
*/
public int getCount() {
return count;
}
}
And my first task is to find the longest word from the given file list.
This is my attempt(I know it's wrong, but can't follow examples, because the solutions I see use the array directly):
public class Search {
/**
* Returns the index of the longest string in the list.
* If there are several string of this length, the
* indexed returned is the that of the first.
* #param a list of strings, in ascending order
* #return position of an entry with the longest string in the list
*/
public int longestWord(StringList a) {
int i=0;
int longestWord=0;
String nextWord=a.get(i+1);
String previousWord=a.get(i);
while (i < a.size() ) {
if (nextWord.length()>previousWord.length()){
longestWord = i;
}
i = i + 1;
}
return longestWord;
}
The result should be "14", the world "because" is the 15th word and is the longest. I hope you can help me with this!
list of words
public class Search {
/**
* Returns the index of the longest string in the list.
* If there are several string of this length, the
* indexed returned is the that of the first.
* #param a list of strings, in ascending order
* #return position of an entry with the longest string in the list
*/
public int longestWord(StringList a) {
int length=a.get(0).length();
int i=0;
int longestWord=0;
while (i<a.size()){
if (a.get(i).length()>length){
length=a.get(i).length();
longestWord=i;
}
i = i + 1;
}
return longestWord;
}
managed to do it :P

Code reads "null" in the first element of the array

I'm pretty new to the world of coding and I have a problem.
I'm creating a simple java class that reads strings from an array but every time I run the program, I get a "null" in my very first element.
This is my code:
public class Airline {
/* Fields */
private String name;
private String[] list;
private int size = 0;
private int DEFAULT_SIZE = 1;
/* Constructor */
public Airline() {
list = new String[DEFAULT_SIZE] ; // creates an airline array
}
/* Methods */
// method that adds "airline name" into the array
public void add(String name) {
this.name = name;
//a new array with + 1 index
String[] temp = new String[list.length + 1];
//copy items from list[] to temp[]
for (int i = 0; i < list.length; i++) {
temp[i] = list[i];
}
// add the last integer to new temp
temp[temp.length - 1] = name;
list = temp;
}
// method that reads from the array start
public int read(int read) {
for (int i = 0; i < list.length; i ++) {
Airline temp = new Airline();
System.out.println("Airline: " + list[i]);
}
return size;
}
And this is my test class:
public class TestAirline {
public static void main(String[] args) {
//create the object
Airline airline = new Airline();
// add airline names
airline.add("Air Canada");
airline.add("West Jet");
airline.add("Sunwing Airlines");
airline.add("Air Transat");
airline.add("Emirates");
airline.add("Cathay Pacific");
airline.add("Etihad");
airline.add("British Airways");
airline.add("Delta Airlines");
airline.add("United Airlines");
airline.add("American Airlines");
airline.add("Porter Airlines");
//read the array
airline.read(0);
}
But this is my output, I get a "null" in my very first element and I don't know why
Airline: null
Airline: Air Canada
Airline: West Jet
Airline: Sunwing Airlines
Airline: Air Transat
Airline: Emirates
Airline: Cathay Pacific
Airline: Etihad
Airline: British Airways
Airline: Delta Airlines
Airline: United Airlines
Airline: American Airlines
Airline: Porter Airlines
It's because you start with a list of length 1.
When you create an array in Java, its elements are initialized to the default value for the type; for objects, that's null. So, you start off with an array containing null.
When you call add, you append the new string to the end of the list; but you never overwrite elements, so that null is not overwritten.
Set DEFAULT_ZERO to zero, and you won't have this null in the array initially.
You should strongly consider using an ArrayList instead of manually resizing the array like this. At the very least, you should read about ArrayList's resizing strategy, which is to double in length when you run out of space. Resizing by 1 each time is very inefficient.
That is because you do
temp[temp.length - 1] = name;
Where temp.length is already at 2.
Which means you write name in temp[1] instead of temp[0]
As others answers pointed, you should use ArrayList. But if you want to build it yourself for learning purpose...
public class Airline {
/* Fields */
private String name; //This is useless as you never really need it
private String[] list;
private int size = 0; //This is useless as you never really use it
private int DEFAULT_SIZE = 1; //This is useless as you never really need it
/* Constructor */
public Airline() {
// list = new String[DEFAULT_SIZE] ;
/* The line above is useless as you are wasting space. If you want to use an array, then you should initialize it only when you want to put the first element inside. */
}
/* Methods */
// method that adds "airline name" into the array
public void add(String name) {
/* The argument name already hold the "name" of the latest airline */
//this.name = name;
//a new array with + 1 index
//Just check if list is null here
if(list==null) list = new String[1]; list[0] = name;
else {
String[] temp = new String[list.length + 1];
//copy items from list[] to temp[]
for (int i = 0; i < list.length-1; i++) {
temp[i] = list[i];
}
// add the last integer to new temp
temp[temp.length - 1] = name;
list = temp;
}
}
// method that reads from the array start
public int read() {
//Notice you don't need the argument read as you always read from the start, if you wanted to read from the index read, replace i=0 below by i=read and add the argument
for (int i = 0; i < list.length; i ++) {
Airline temp = new Airline(); //And as far as I know, you don't need this too
System.out.println("Airline: " + list[i]);
}
return size;
}

What's wrong with my method that checks if an array of strings is sorted

I am doing a Java class and I cannot figure it out where I am wrong.
I have a class called ArrayMethods and a method that I must use to see if my arrays are sorted or not. This is my code:
public class ArrayMethods
{
String[] list; //instance variable
/**
* Constructor for objects of class ArrayMethods
*/
public ArrayMethods(String[] list)
{
// initialise instance variables
this.list = list;
}
/**
* Determines if the array is sorted (do not sort)
* When Strings are sorted, they are in alphabetical order
* Use the compareTo method to determine which string comes first
* You can look at the String compareTo method in the Java API
* #return true if the array is sorted else false.
*/
public boolean isSorted()
{
boolean sorted = true;
// TODO: Write the code to loop through the array and determine that each
// successive element is larger than the one before it
for (int i = 0; i < list.length - 1; i++){
if (list[i].compareTo(list[i + 1]) < 0){
sorted = true;
}
}
return sorted;
}
}
And then I have a tester for this arrays that goes like this:
public class ArrayMethodsTester {
public static void main(String[] args) {
//set up
String[] animals = {"ape", "dog", "zebra"};
ArrayMethods zoo = new ArrayMethods(animals);
//test isSorted
System.out.println(zoo.isSorted());
System.out.println("Expected: true");
String[] animals2 = {"ape", "dog", "zebra", "cat"};
zoo = new ArrayMethods(animals2);
System.out.println(zoo.isSorted());
System.out.println("Expected: false");
String[] animals3 = {"cat", "ape", "dog", "zebra"};
zoo = new ArrayMethods(animals3); ;
System.out.println(zoo.isSorted());
System.out.println("Expected: false");
}
}
For the first array I do get true as it is normal, the problem is that I get true for the other 2 and it is clearly that this is false. What is it that I do not get?
could make it a little simpler by directly returning false inside of the loop
for (int i = 0; i < list.length - 1; i++) {
if (list[i].compareTo(list[i + 1]) > 0) {
return false;
}
}
return true;
public class ArrayMethods
{
String[] list; //instance variable
/**
* Constructor for objects of class ArrayMethods
*/
public ArrayMethods(String[] list)
{
// initialise instance variables
this.list = list;
}
/**
* Determines if the array is sorted (do not sort)
* When Strings are sorted, they are in alphabetical order
* Use the compareTo method to determine which string comes first
* You can look at the String compareTo method in the Java API
* #return true if the array is sorted else false.
*/
public boolean isSorted()
{
boolean sorted = true;
// TODO: Write the code to loop through the array and determine that each
// successive element is larger than the one before it
for (int i = 0; i < list.length - 1; i++){
if (list[i].compareTo(list[i + 1]) > 0){
sorted = false;
break;
}
}
return sorted;
}
}`
You could also do it with Java 8 streams if you like their syntax (though it is not a perfect use case for them because you need two elements of the stream for your operation):
public static boolean isSorted(final String[] array) {
return !IntStream.range(1, array.length)
.mapToObj(i -> new Pair<String>(array[i - 1], array[i])).parallel()
.anyMatch(t -> t.first.compareTo(t.second) > 0);
}
The code uses a small helper class Pair
public static final class Pair<T> {
final T first;
final T second;
private Pair(final T first, final T second) {
this.first = first;
this.second = second;
}
}
This solution could also run parallel which would make it faster when running on large arrays.
Credits to Collect successive pairs from a stream for accessing a Pair of elements with streams

How to import Java file method to another Java file?

I have two Java files, one called Assign_2 and another called ArrayMath. I want to allow ArrayMath's methods to be used in Assign_2 like so:
ArrayMath.arrayAddition(a, b); //Called ArrayMath from Assign_2.java
What code allows ArrayMath.java methods to be used in Assign_2.java?
public class Assign_2 {
/**
* Main method to execute whole code.
*
* #param theArgs is used to keep consistency
*/
public static void main(String[] theArgs) {
Scanner input = null; // For file input
PrintStream output = null; // For file output
String inFileName = "in2a.txt"; //Input file and outputs
String outFileName = "out.txt";
boolean filesOk = false; // Checks for files to be accessed
int[][] a = null; // Declaring the 4 arrays for operations
int[][] b = null;
int[][] c = null;
int[][] d = null;
// Opens file for input and readys for output
try {
input = new Scanner(new File(inFileName));
output = new PrintStream(new File(outFileName));
filesOk = true;
}
catch (FileNotFoundException e) {
System.out.println("Can't open file - " + e);
}
if (filesOk) {
a = get2DArray(input);
b = get2DArray(input);
c = get2DArray(input);
d = get2DArray(input);
// Sanity check for what is in the array and if right
//System.out.println(Arrays.deepToString(a));
//System.out.println(Arrays.deepToString(b));
//System.out.println(Arrays.deepToString(c));
//System.out.println(Arrays.deepToString(d));
// Calling to ArrayMath.java for operation results
// Declaring arrays for final results
int[][] sum = ArrayMath.arrayAddition(a, b);
System.out.println(Arrays.deepToString(sum));
//int[][] difference = ArrayMath.arraySubtraction(a, b);
//int[][] multiplication = ArrayMath.arrayMultiply(a, b);
}
}
/**
* get2DArray reads input file then creates 2D array
* from the file.
*
* #param input is a Scanner to input the file
*
* #return a 2D integer array filled with input values
*/
public static int[][] get2DArray(Scanner theIn) {
int rowSize = theIn.nextInt(); // Takes the first 2 numbers
int colSize = theIn.nextInt(); // that provided column + row #'s
int[][] a = new int[rowSize][colSize]; // New array with ^ #'s
// For loops that add integers to arrays
for (int i = 0; i < a.length; i++) {
for (int k = 0; k < a[i].length && theIn.hasNextInt(); k++) {
a[i][k] = theIn.nextInt();
}
}
return a; // Returns value to main method that was called from
}
}
And ArrayMath.java is:
public class ArrayMath {
/**
* Addition for 2D Arrays method
*
* #param theA and theB are 2D arrays from Assign_2
*
* #return sum to Assign_2 main program
*/
public static int[][] arrayAddition(int[][] theA, int[][] theB) {
int[][] sum = new int[theA.length][theA.length];
for (int i = 0; i < theA.length; i++) {
for (int k = 0; k < theA[i].length; k++) {
sum[i][k] = theA[i][k] + theB[i][k];
}
}
return sum;
}
}
What you need is to define the method(s) in ArrayMath as public and static, e.g.:
public static void arrayAddition(int a, int b)
{
// do something
}
Define the method in you want to import ArrayMath.java as static.
Assume the wrapper class is just called ArrayMath, make it a public method and then from Assign_2 do import ArrayMath.
refer to the method like ArrayMath.yourMethod().
Call the method after you create an object for ArrayMath class:
ArrayMath ob = new ArrayMath();
Then call the method in Assign_2 class asfollowing
ob.arrayAddition(a, b);
Make sure the method is public.
What all you have to do is to create an object from ArrayMath and use the method declared inside Assign_2
E.g:
ArrayMath obj = new ArrayMath();
obj.arrayAddition(a, b);
Read more about creating objects in Java
There are multiple ways
1. inheritance is-a relationship
2. composition has-a relationship - but in case of has-a relationship you have to made public and static to your method to call from another class.

Why am I getting an ArrayIndexOutOfBounds exception when array size defined in class?

For my project, a user must define the size of an array, and I created a set method to do this. The variable being changed is the class variable, arraySize. But, when someone sets the array size, and I try adding an array, I receive an indexoutofbounds error.
Here's the snippet of code
//Size of the array
private int arraySize;
//initializes elemnt count of array
private int arrayElementCount;
//Gets count of SID in array
public int getSIDArrayCount() {
//returns private variable
return arrayElementCount;
}
//Sets SID Array
public void setArraySize(int setArraySize) {
//Array size int
//checks array if array size is greater than 0
if (setArraySize > 0) {
//sets array size
//SIDArray
arraySize = setArraySize;
}
}
//SIDArray
private String[] SIDArray = new String[arraySize];
EDIT:
I can't initialize the array in the 'setArraySize' method because I need an accessor method for the array.
here's the rest of the class:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ahellhound.pkg202sidproject;
import java.util.Arrays;
import java.util.regex.Pattern;
/**
*
* #author Colby Leclerc
*/
public class SIDArrayTest {
//Size of the array
private int arraySize;
//initializes elemnt count of array
private int arrayElementCount;
//Gets count of SID in array
public int getSIDArrayCount() {
//returns private variable
return arrayElementCount;
}
//Sets SID Array
public void setArraySize(int setArraySize) {
//Array size int
//checks array if array size is greater than 0
if (setArraySize > 0) {
//sets array size
//SIDArray
arraySize = setArraySize;
}
}
//SIDArray
private String[] SIDArray = new String[arraySize];
//Gets SID Array
public String[] getSIDArray() {
//returns array
return SIDArray;
}
//Validates SID; returns true if SID entry is valid
public boolean validateSID(String SIDEntry) {
//checks if sid entry is 7, and if starts with s
if (SIDEntry.length() != 7) {
//retuns false
return false;
}
//checks if SIDEntry begins with 'S'
if (!SIDEntry.matches("[sS]\\d{6}")) {
//returns false
return false;
}
//returns true
return true;
}
//Adds SID to the Array
public void addSID(String SIDEntry) {
//checks if SID is valid
if (validateSID(SIDEntry)) {
//Adds sid to array
SIDArray[arrayElementCount] = SIDEntry;
//increases array size by one
arrayElementCount++;
} else {
System.out.println("test failed 2");
}
}
//Gets SID array and returns all entrys to strings
public String getSIDArrayString() {
//Gets array and converts to string
String SIDArrayString = Arrays.toString(SIDArray);
//returns array string
return SIDArrayString;
}
}
I am truly stumped at how to set the array size, when I've created a class variable for it, while having the array a 'get'-able method.
You are instantiating the array before calling your setArraySize-method, thus it gets size of 0.
//SIDArray
private String[] SIDArray = new String[arraySize];
As the SIDArray variable is in the scope of the class, it gets instantiated as soon as an object of the class is created. Because of this, it uses the arraySize varible, which is uninstantiated at this point(and defaults to 0 in case of an int).
To fix this, simply instantiate the array after calling setArraySize().
Here is some code to clarify what I meant in the comments.
public class A {
/* In your code, you instantiate the array at this point, in the scope of the class, while arraySize is still uninitialized */
String[] array; /* uninitialized, defaults to null */
int arraySize; /* uninitialized, defaults to 0 */
/* Simple accessor method for the array */
public String[] getArray() {
return array;
}
public int getArraySize() {
return arraySize;
}
public void setArraySize(int size) {
this.arraySize = size;
}
public void createArray() {
array = new String[arraySize];
}
}
You have to initialize the array variable after you set the new size. Change your method to:
//Sets SID Array
public void setArraySize(int setArraySize) {
//Array size int
//checks array if array size is greater than 0
if (setArraySize > 0) {
//sets array size
//SIDArray
arraySize = setArraySize;
SIDArray = new String[arraySize];
}
}
The problem is that you are instantiating an array with a fixed size (0). That's not necessarily bad... the real problem is that in you setArraySize(int setArraySize) method, you update your arraySize variable, but the array is never aware of this call!!!
You should use something like
SIDArray = new String[arraySize];
But even if you do this, resizing your array will destroy all its previous contents... just be aware of this.

Categories