Creating an Array List from scratch - java

I was wondering if anyone would be able to point me in the correct direction in regards to creating my own array list methods. For instance, the current project I am assigned to does not allow for me to use the methods given to me for free like in the following example.
package com.tutorialspoint;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(22);
arrlist.add(30);
arrlist.add(40);
// adding element 25 at third position
arrlist.add(2,25);
// let us print all the elements available in list
for (Integer number : arrlist) {
System.out.println("Number = " + number);
}
}
}
This example shows the add() method. For my project I have to create this method myself and call it from a different file within my package.

I find this as an interesting problem. I am always curious about how things work at the raw level.
If you think about it, an ArrayList is basically just an array that you can expand. So you can either have a really big array (which would take a lot of memory for one ArrayList) or every time you add something, you make a new bigger array and copy the contents and add the new item (which I think the performance is O(N)).
This is my attempt without using any libraries:
public class MyArrayList<T>
{
private T[] asArray;
#SuppressWarnings("unchecked")
public MyArrayList()
{
asArray = (T[]) new Object[0];
}
public void add(T t)
{
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length + 1];
// copy everything over to the new array
for (int i = 0; i < asArray.length; i++)
{
temp[i] = asArray[i];
}
// add the new element
temp[asArray.length] = t;
asArray = temp;
}
public void remove(int index)
{
if (index < 0 || index >= asArray.length) return;
#SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[asArray.length - 1];
boolean found = false;
// copy everything over to the new element
for (int i = 0; i < asArray.length; i++)
{
// don't copy if the indices are the same
if (i == index)
{
found = true;
continue;
}
temp[i - (found ? 1 : 0)] = asArray[i]; // it's i - 1 after the removed object so then it doesn't leave a gap and it doesn't go over the array's length
}
asArray = temp;
}
public T get(int index)
{
return asArray[index];
}
}
I am quite proud of this code. :) I consider Short_Teeth's code cheating because the class is a subclass and, well, doesn't add anything. I hope I helped.

This is very easy to understand; However, I explained a little bit in comments.
public class MyArrayList<E extends Object> {
private static int initialCapacity = 5;
private static int currentSize;
private Object[] myArrayList = {}, temp = {};
private static int currentIndex = 0;
public static void main(String[] args) {
MyArrayList arrList = new MyArrayList();
arrList.add("123"); //add String
arrList.printAllElements();
arrList.add(new Integer(111)); //add Integer
arrList.printAllElements();
arrList.add(new Float("34.56")); //add Integer
arrList.printAllElements();
arrList.delete("123");
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
arrList.delete(123);
arrList.printAllElements();
}
public MyArrayList() { //creates default sized Array of Objects
myArrayList = new Object[initialCapacity]; //generic expression
/* everytime I cross my capacity,
I make double size of Object Array, copy all the elements from past myObject Array Object
*/
}
public MyArrayList(int size) { //creates custom sized Array of Objects
myArrayList = new Object[size];
}
public void add(Object anyObj) {
//add element directy
myArrayList[currentIndex] = anyObj;
currentSize = myArrayList.length;
currentIndex++;
if (currentIndex == currentSize) {
createDoubleSizedObjectArray(currentSize);
}
}
//print all elements
public void printAllElements() {
System.out.println("Displaying list : ");
for (int i = 0; i < currentIndex; i++) {
System.out.println(myArrayList[i].toString());
}
}
private void createDoubleSizedObjectArray(int currentSize) {
temp = myArrayList.clone();
myArrayList = new MyArrayList[2 * currentSize]; //myObject pointer big size data structure
// myObject = temp.clone(); //probably I can do this here as well. Need to check this
System.arraycopy(temp, 0, myArrayList, 0, currentSize);
}
void delete(Object object) {
//if already empty
if (currentIndex == 0) {
System.out.println("Already empty!");
return;
}
//you don't need to delete anything. I can simply override the storage
currentIndex--;
}
}

import java.util.ArrayList;
public class MyArrayList<E> extends ArrayList<E>{
private static final long serialVersionUID = -5164702379587769464L;
public void newMethod(){
// No implementation
}
}
This is a class which extends from ArrayList and a method called newMethod() was added to this class.
Below we are calling this newly created method in your case you must implement the add to this newly created method.
public class Hello {
public static void main(String args[]) {
MyArrayList<Integer> myList = new MyArrayList<Integer>();
// It has the ArrayList add() method as this new class extends from ArrayList (all the ArrayList methods are included)
myList.add(2);
// The newly created method in your case you need to implement the add yourself
myList.newMethod();
}
}
This could also be a good link for what you need.
http://www.java2novice.com/java-interview-programs/arraylist-implementation/
I also recomend that you try to implement and solve your problems first and then ask questions about a specific problem, and only after you done a good research about what may be causing this problem (There are lots of resources out there). If you done some research before you asked this question, I'm pretty sure that you would have been able to solve everything on your own.
Hope you find this information useful. Good luck.

Related

Problem in implementing the methods according to test file

I was able to make the Constructor and capacity methods to works but don;t know why size(),isFull() and isEmpty() fails.I believe its pretty simple but i am just unable to see a minor error and fix it.Hope someone can clarify what i am doing wrong with thorough explaination.Also,my constructor works with the test file and it passes,but just want to know Is my constructor correct as specified by question?
import java.util.Arrays;
import java.util.Iterator;
public class SortedArray<T extends Comparable> implements
java.lang.Iterable<T> {
public SortedArray(int capacity) {
this.array = (T[]) new Comparable[0];
this.capacity = capacity;
this.size = 0;
}
public SortedArray(int capacity, T[] data) {
if(capacity > data.length)
{
this.capacity = capacity;
}
else {
this.capacity = data.length;
}
this.size = data.length;
this.array = (T[]) new Comparable[0];
}
final public int size() {
return this.size
}
final public int capacity() {
return this.capacity;
}
final boolean isEmpty() {
return size == 0;
}
final boolean isFull(){
return size == capacity;
}
#Override
final public Iterator<T> iterator() {
// Do not modify this method.
return Arrays.stream(array).iterator();
}
// Do not modify these data members.
final private T[] array; // Storage for the array's element
private int size; // Current size of the array
final private int capacity; // Maximum size of the array
}
//// Test File:
#Test
public void testConstructor() {
System.out.println("Constructors");
SortedArray array = new SortedArray(20);
assertEquals(array.size(), 0);
assertEquals(array.capacity(), 20);
Integer[] data = {1, 2, 3, 4};
array = new SortedArray(20, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 20);
array = new SortedArray(2, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 4);
}
#Test
public void testSize() {
System.out.println("size");
SortedArray arr = new SortedArray(10);
// Array is initially empty
assertEquals(arr.size(), 0);
// Inserting elements increases size
arr.add(12);
arr.add(13);
arr.add(14);
assertEquals(arr.size(), 3);
// Inserting duplicates increases size
arr.add(12);
arr.add(13);
assertEquals(arr.size(),5);
// Fill up the array
for(int i = 0; i < 5; ++i)
arr.add(i);
assertEquals(arr.size(), 10);
// Size does not change when array is full
arr.add(10);
arr.add(11);
assertEquals(arr.size(), 10);
// Removing elements decreases size
arr.remove(0);
arr.remove(1);
arr.remove(2);
assertEquals(arr.size(), 7);
// but removing elements that don't exist doesn't change anything
arr.remove(100);
assertEquals(arr.size(), 7);
// Removing from the empty array doesn't change size.
SortedArray empty = new SortedArray(10);
empty.remove(10);
assertEquals(empty.size(), 0);
}
#Test
public void testCapacity() {
System.out.println("capacity");
SortedArray array = new SortedArray(20);
assertEquals(array.capacity(), 20);
array = new SortedArray(100);
assertEquals(array.capacity(), 100);
Integer[] data = {1,2,3,4,5,6,7,8,9,0};
array = new SortedArray(20, data);
assertEquals(array.capacity(), 20);
array= new SortedArray(5, data);
assertEquals(array.capacity(), 10);
}
#Test
public void testIsEmpty() {
System.out.println("isEmpty");
SortedArray array = new SortedArray(10);
assertTrue(array.isEmpty());
array.add(10);
assertFalse(array.isEmpty());
array.remove(10);
assertTrue(array.isEmpty());
}
#Test
public void testIsFull() {
System.out.println("isFull");
SortedArray array = new SortedArray(5);
assertFalse(array.isFull());
array.add(10);
array.add(11);
array.add(12);
array.add(13);
array.add(14);
assertTrue(array.isFull());
array.remove(10);
assertFalse(array.isFull());
}
#Test
public void testIterator() {
}
testSize Failed : Expected <0> but was <3>
testCapacity Failed : Expected <5> but was <10>
testConstructor Failed : Expected <0> but was <4>
testisFull Failed : jUnit.framework.AssertionFailedError
testisEmpty Failed : jUnit.framework.AssertionFailedError
You forgot to include your "add(T toAdd)" and "remove(T toRemove)" methods, which when I was going through to make the tests pass, was the source of a vast majority of the fails. (Note: a trace of the fails would help, since your adds and removes need to be pretty complicated to fit the design it seems you intend)
Anyways, on to fixing what I can see.
In your second constructor, you never actually assign the data you take in. You call this.array = (T[]) new Comparable[0]; which creates an empty array of type Comparable. In reality, you need to call this.array = data in order to keep what's been given to you.
Another thing, in your size() method you forgot to place a semicolon after this.size. That tends to prevent things from passing.
Finally, final private T[] array can't have final, or you'll never be able to add or remove elements.
As a bonus, here are the add() and remove() methods I used to fit the requirements and make the tests pass (with comments!!!!):
public void add(T t) {
if (!(size >= capacity)) { //If there's room...
if (size == 0) //If the array is empty...
array[0] = t; //Add to first index
else
array[size] = t; //Add to next available index
size++;
}
}
public void remove(T element) {
if (size <= 0) //If the array is empty...
return; //Stop here
else {
for (int i = 0; i <= this.size(); i++) { //Linear search front-to-back
if (array[i].equals(element)) { //Find first match
array[i] = null; //Delete it
size--;
if (i != size) { //If the match was not at the end of the array...
for (int j = i; j <= (this.size() - 1); j++)
array[j] = array[j + 1]; //Move everything after the match to the left
}
return; //Stop here
}
}
}
}
On a side note, your calls to create SortedArray objects should really be parameterized (Using the <> such as SortedArray<Integer> arr = new SortedArray<Integer>(5, data);).

Sorting String array gives NullPointerException

Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));

How to decide the state of an object before starting to code?

I have the following code for displaying the sum of two consecutive element of ArrayList until the element left is one.for example:-
if i entered
1 2 3 4 5
output
3 7 5 //adding the two consecutive last one is as it is
10 5//doing the same thing
15
code
import java.util.*;
import java.lang.Integer;
class Substan{
ArrayList <Integer> list = new ArrayList <Integer> ();
ArrayList <Integer> newList = new ArrayList <Integer> ();// this will be the list containing the next sequence.
int index=0;
int sum=0;
Substan(){
Scanner read = new Scanner(System.in);
String choice;
System.out.println("Enter the elements of the array");
do{
int element = read.nextInt();
list.add(element);
System.out.println("More?");
choice = read.next();
}while(choice.equals("y") || choice.equals("Y"));
}
/* precondition- we have the raw list that user has enterd.
postcondition - we have displayed all the sublists,by adding two consecutives numbers and the last one is having one element.
*/
void sublist(){
while(noofElementsIsNotOneInList()){
index =0;
while(newListIsNotComplete()){
if(nextElementIsThere()){
sum = addTheConsecutive();
}
else{
sum = getLastNumber();
}
storeSumInNewList();
}
displayTheNewList();
System.out.println("");
updateTheLists();
}
displayTheNewList(); //as we have danger of Off By One Bug (OBOB)
System.out.println("");
}
private boolean noofElementsIsNotOneInList(){
boolean isnotone = true;
int size = list.size();
if ( size == 1){
isnotone = false;
}
return isnotone;
}
private boolean newListIsNotComplete(){
boolean isNotComplete = true;
int listSize = list.size();
int newListSize = newList.size();
if (listSizeIsEven()){
if ( newListSize == listSize/2){
isNotComplete = false;
}
}
else{
if( newListSize == (listSize/2) +1){
isNotComplete = false;
}
}
return isNotComplete;
}
private boolean listSizeIsEven(){
if ( list.size()%2 == 0 ){
return true;
}
else{
return false;
}
}
/*
we are at some index.
returns true if we have an element at (index+1) index.
*/
private boolean nextElementIsThere(){
if ( list.size() == index+1 ){
return false;
}
else{
return true;
}
}
/* precondition-we are at index i
postcondition - we will be at index i+2 and we return sum of elements at index i and i+1.
*/
private int addTheConsecutive(){
int sum = list.get(index)+list.get(index+1);
index += 2;
return sum;
}
/* we are at last element and we have to return that element.
*/
private int getLastNumber(){
return list.get(index);
}
private void storeSumInNewList(){
newList.add(sum);
}
private void displayTheNewList(){
int size = newList.size();
for ( int i=0;i<size;i++){
System.out.print(newList.get(i)+" ");
}
}
/*precondition - we have processed all the elements in the list and added the result in newList.
postcondition - Now my list will be the newList,as we are processing in terms of list and newList reference will have a new object.
*/
private void updateTheLists(){
list = newList;
newList = new ArrayList <Integer>();// changing the newList
}
public static void main(String[] args) {
Substan s = new Substan();
s.sublist();
}
}
So i have done a lot of refinement of my code but having a problem of sharing the local variables with the other methods.for example i have used index instance for storing the index and initially i thought that i will put this as not an instance but a local variable in method sublist() but as it cannot be viewed from other methods which needed to use the index like addTheConsecutive().So considering that i put the index at class level.So is it wright approach that put the variables that are shared at class level rather than looking at only the state of the object initially before coding and stick to that and never change it?
Consider this:
An object can communicate with other(s) only by sharing its attributes. So, if you need an object to read the state of another, the only way it can be done is by giving it "permission" to read the other object attributes.
You have two ways to do that:
Declaring the object attributes public, or
Creating getXXX() methods (makes sense for private attributes)
I personally prefer option two, because the getXXX() method returns the value ("state") of a particular attribute without the risk of being modified. Of course, if you need to modify a private attribute, you should also write a setXXX() method.
Example:
public class MyClass {
private int foo;
private String bar;
/*
* Code
*/
public int getFoo() {
return foo;
}
public String getBar() {
return bar;
}
public void setFoo(int foo) {
this.foo = foo;
}
public void setBar(String bar) {
this.bar = bar;
}
/*
* More code
*/
}
This way all the object attributes are encapsulated, and:
they cannot be read by any other object, unless you specifically call the appropriate getXXX() function, and
cannot be altered by other objects, unless you specifically call the appropriate setXXX() function.
Compare it with the non-abstracted version.
for (int index = 0; index < list.size(); index += 2) {
int sum = list.get(index);
if (index + 1 < list.size() {
sum += list.get(index + 1);
}
newList.add(sum);
}
Now, top-down refining the algorithm using names is a sound methodology, which helps in further creative programming.
As can seen, when abstracting the above again:
while (stillNumbersToProcess()) {
int sum = sumUpto2Numbers();
storeSumInNewList(sum);
}
One may keep many variables like sum as local variables, simplifying state.
One kind of helpful abstraction is the usage of conditions, in a more immediate form:
private boolean listSizeIsEven() {
return list.size() % 2 == 0;
}
private boolean nextElementIsThere() {
return index + 1 < list.size();
}
There's no point in declaring index at Class level since you dont want it to be a member or an instance of that class. Instead make it local to the method and pass it to other methods as argument where you want to access it.
I think you are asking the wrong question.
Your class variables make very little sense, as do many of the methods. This is mostly because:
Your class is doing too much
Your algorithm is a little odd
The class variables that you do have make much more sense passed as method parameters. Some methods need to see them, and some don't.
Your class is also a little odd, in that calling subList twice on the same class will not produce the same answer.
The code is littered with methods I don't quite see the point in, such as:
private boolean noofElementsIsNotOneInList(){
boolean isnotone = true;
int size = list.size();
if ( size == 1){
isnotone = false;
}
return isnotone;
}
Shouldn't this be:
private boolean noofElementsIsNotOneInList(){
return list.size() == 1;
}
And it makes no sense for it to use some arbitrary List, pass one in so that you know which List you are checking:
private boolean noofElementsIsNotOneInList(final Collection<?> toCheck){
return toCheck.size() == 1;
}
The same logic can be applied to almost all of your methods.
This will remove the instance variables and make your code much more readable.
TL;DR: Using lots of short appropriately named methods: good. Having those methods do things that one wouldn't expect: bad. Having lots of redundant code that makes things very hard to read: bad.
In fact, just to prove a point, the whole class (apart from the logic to read from stdin, which shouldn't be there anyway) can transformed into one short, recursive, method that requires no instance variables at all:
public static int sumPairs(final List<Integer> list) {
if (list.size() == 1)
return list.get(0);
final List<Integer> compacted = new LinkedList<>();
final Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
final int first = iter.next();
if (iter.hasNext()) compacted.add(first + iter.next());
else compacted.add(first);
}
return sumPairs(compacted);
}
Now you could break this method apart into several appropriately named shorter methods, and that would make sense. It's sometimes more helpful to start from the other end. Sketch out the logic of your code and what it's trying to do, then find meaningful fragments to split it into. Possibly after adding unit tests to verify behaviour.
what about doing by Recursion:
public int calculateSum(List<Integer> nums) {
displayList(nums);
if (nums.size() == 1) {
return nums.get(0);
}
List<Integer> interim = new ArrayList<Integer>();
for (int i = 0; i < nums.size(); i = i + 2) {
if (i + 1 < nums.size()) {
interim.add(nums.get(i) + nums.get(i + 1));
} else {
interim.add(nums.get(i));
}
}
return calculateSum(interim);
}
public static void displayList(List<Integer> nums){
System.out.println(nums);
}
Steps:
Run calculate sum until list has 1 element
if list has more than 1 element:
iterate the list by step +2 and sum the element and put into a new List
again call calculate sum

Am I not understanding ArrayList or am I missing something?

I'm trying to create a very, very simple program.
I want my class called Text to simply print out a string, specifically, one letter.
Then in my second class called Window, I want to create an ArrayList of that class, iterate through the list and call the method of my Text class to print out the string. But it does not print anything.
What am I doing wrong?
public class Text {
private String a;
public void printA() {
a = "a";
System.out.print(a);
}
}
and the other class..
import java.util.ArrayList;
public class Window {
private ArrayList<Text> string = new ArrayList<Text>(5);
public Window() {
addText();
}
public void iterate() {
for (int i = 0; i < string.size() - 1; i++) {
string.get(i).printA();
}
}
public void addText() {
for (int i = 0; i <string.size() - 1; i++) {
string.add(new Text());
}
}
public static void main(String[] args) {
Window wind = new Window();
wind.iterate();
}
}
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
initialy the arraylist is empty, so string.size() == 0
the forlus wil not be executed, change to
public void addText(){
string.add(new Text())
}
or even better
public void addText(Text t){
string.add(t)
}
that way you can add Text-object created with different constructors
If you modify iterate to:
public void iterate(){
System.out.println(string.size()-1);
for(int i = 0; i < string.size()-1;i++){
string.get(i).printA();
}
}
You will get -1
Let me explain why:
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. private ArrayList<Text>string = new ArrayList<Text>(5); merely sets the capacity of the underlying array that is the data structure that implement the ArrayList object. size() returns the number of objects inside of the ArrayList not the capcity
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
The for loop's expression doesn't evaluate to true, and therefore you never add a single object to the loop which is why iterate would print -1 if you added the print statement there
The
new ArrayList<Text>(5);
Doesn't mean you have 5 elements array. It means that this is just initial capacity of internal array for storing elements. Due to this your init code:
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
faces no elements in the list with string.size() = 0.
Use this instead (If you like to add 5 elements):
public void addText(){
for(int i = 0; i < 5;i++){
string.add(new Text());
}
}
There is no problem to add more elements (even if the initial capacity was only '5'). From docu "As elements are added to an ArrayList, its capacity grows automatically."
problem it this method.
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
this doesn't add anything at all. because string.size() is 0.
may be you should change it to
public void addText(int size){
for(int i = 0; i <size-1;i++){
string.add(new Text());
}
}
Ps: new Arraylist<Text>(5) actually creates an empty list with initial capacity = 5 (not size). See it here
Well for stater your method in Text needs parameter so it KNOWS to take in 'a' and if you're variable in your parameter is going to be 'a' as well you need use "this." so that the compiler knows that the two are different.
public class Text {
private String a;
public void printA(String a) {
this.a = "a";
System.out.print(a);
}
}
What you are doing wrong is that you are creating the ArrayList with a capacity of 5, but it does not yet have 5 objects in it. Thus, the addText method does nothing. Here's a version that works:
public void addText(){
for(int i = 0; i < 4; i++){
string.add(new Text());
}
}
Note that string.size() - 1 has been changed to 4, becuase string.size() is 0, and you want to add 4 elements to the list. Also, your iterate method could use a little refactoring:
public void iterate(){
for(Text text : string){
string.get(i).printA();
}
}
Instead of a simple loop, an enhanced for is used instead. This is no more than a typing shortcut, but it improves efficiency for LinkedLists.

Java error "Undefined name"

I've tried fixing this I just cant seem to find a solution to this problem. The code is meant to print the prime numbers in a range, but it just returns the error
Static Error: Undefined name 'PrimeNumbers
Would anyone please be able to help me ?
This is my code :
import java.util.*;
public class PrimeNumbers {
private List<Integer> listOfPrimeNumbers; //add a member variable for the ArrayList
public static void main(String args []){
PrimeNumbers primeNumberList = new PrimeNumbers(50);
primeNumberList.print(); //use our new print method
}
public PrimeNumbers (int initialCapacity) {
listOfPrimeNumbers = new ArrayList<Integer>(initialCapacity/2); //initialCapacity/2 is an easy (if not tight) upper bound
long numberOfPrimes = 0; //Initialises variable numberOfPrimes to 0
int start = 2;
boolean[] isPrimeNumber = new boolean[initialCapacity + 1];
for (int i=0;i==initialCapacity;i++) {//setting all values in array of booleans to true
isPrimeNumber[i] = true;
}
while (start != initialCapacity)
{
if (isPrimeNumber[start])
{
listOfPrimeNumbers.add(start);
//add to array list
numberOfPrimes++;
for (int i = start; start < initialCapacity; i+=start)
{
isPrimeNumber[i] = false;
}
}
start++;
}
}
public void print() {
int i = 1;
for (Integer nextPrime:listOfPrimeNumbers) {
System.out.println("the " + i + "th prime is: " + nextPrime);
i++;
}
}
//or just System.out.println(listOfPrimeNumbers);, letting ArrayList's toString do the work. i think it will be in [a,b,c,..,z] format
public List getPrimes() {
return listOfPrimeNumbers;
} //a simple getter isnt a bad idea either, even though we arent using it yet
}
Assuming, you have you code organized like this
./project
PrimeNumbers.java
PrimeNumbers.class
then you cd to ./project and type
java PrimeNumbers
Note - this only works because you didn't declare a package (iaw: you class is in the default package). Usually you have a package declaration and then it looks a bit different.
Bonus
The getter is a good idea, but you should think twice before returning a collection, because this way, you grant the receiver full access to your (internal?) datastructure and he can alter the values of that collection. And you shouldn't declare it with the raw type. Here's a better way to implement it:
public List<Integer> getPrimes() {
return Collections.unmodifiableList(listOfPrimeNumbers);
}
Now the receiver knows that he get's a list of Integer values and can't modify the result.

Categories

Resources