Solved

Java - multidimensional ArrayList - How do I add individual items to a nested ArrayList

Posted on 2011-03-16
13
1,158 Views
Last Modified: 2012-05-11
I am working on a final project for my Java class and would like some tips or examples from an expert.

The project is to create an Address Book GUI without using arrays - Collections only.  I decided to use an ArrayList because I've used them before (and I've gotten lots of help from EE).

I have already created a few classes based on previous projects but I have not gotten it right just yet.  One of my requirements is to fill the ArrayLists with sample data for testing.  This I have done, but not correctly (I think).

The nested array contains objects created by reading from an input file.  These objects are added as ArayLists to the main ArrayList.
Here are the classes I have so far; the main class is used, for the moment, to test the functioning of the other two.  I have omitted the GUI classes as they are not yet completed.  These classes function independently at the moment.

the runner class
 
package P4.test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.StringTokenizer;

/**
 *
 * @author gcurrier
 */
public class ArrayListRun {

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        new ArrayListRun();
    }

    /**
     *
     */
    public ArrayListRun(){
        Friend f = new Friend();
        Person p = new Person();
        String inFile = "input.txt";
        try {
            BufferedReader in = new BufferedReader(new FileReader(inFile));
            String buffer = null;
            String delim = ",";
            StringTokenizer t = null;
            while ((buffer = in.readLine()) != null) {
                int i = 0;
                if (buffer.trim().length() == 0) {
                    System.out.println("End of File");
                    continue;
                }
                t = new StringTokenizer(buffer, delim);
                String lName = t.nextToken();
                String mName = t.nextToken();
                String fName = t.nextToken();
                String street = t.nextToken();
                String city = t.nextToken();
                String state = t.nextToken();
                String zip = t.nextToken();
                String hPhone = t.nextToken();
                String cPhone = t.nextToken();
                p = new Person(lName,mName,fName,street,city,state,zip,hPhone,cPhone);
                f.addContactItem(p);
                f.addContactList(f.getContactItemSize()-1, f.getContactItem(i));
                i++;
            }
            int i;
            int ciSize = f.getContactItemSize() - 1;
            int clSize = f.getContactListSize() - 1;
            //int csSize = f.getContactSize() - 1;
            System.out.println("Contact Item ArrayList size: "+f.getContactItemSize());
            System.out.println("PERSON OBJECT : ");
            System.out.println("(contactItem - an ArrayList of Objects.)");
            System.out.println("-----------------------------------------------");
            for (i = 0; i <= ciSize; i++) {
                System.out.println("Index " + i + ": " + f.getContactItem(i));
            }
            System.out.println("\n");
            System.out.println("Contact List ArrayList size: "+f.getContactListSize());
            System.out.println("LIST OBJECT : ");
            System.out.println("(contactList - an ArrayList of ArrayLists)");
            System.out.println("-----------------------------------------------");
            for (i = 0; i <= clSize; i++) {
                System.out.println("Index " + i + ": " + f.getContactList(i));
            }
            System.out.println("\n");
            System.out.println("Size of each ArrayList in contactList: ");
            System.out.println("-----------------------------------------------");
            for (i = 0; i <= clSize; i++) {
                System.out.println("Index " + i + " size : " + f.getContactListObjectSize(i));
            }
                        
//            System.out.println();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Open in new window

the Person Class
 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package P4.test;



/**
 *
 * @author gcurrier
 */
public class Person {

    
    protected String lName, mName, fName, streetName, cityName, stateName, zipcode, hPhone, cPhone;
    /**
     *
     */
    protected int numContacts;

    /**
     *
     */
    public Person() {
        numContacts = 0;
    }

    /**
     *
     * @param person
     */
    public Person(Person person) {
        this.lName = person.getLName();
        this.mName = person.getMName();
        this.fName = person.getFName();
        this.streetName = person.getStreetName();
        this.cityName = person.getCityName();
        this.stateName = person.getStateName();
        this.zipcode = person.getZipcode();
        this.hPhone = person.getHPhone();
        this.cPhone = person.getCPhone();
    }

    Person(String lName, String mName, String fName, String streetName, String cityName, String stateName, String zipcode, String hPhone, String cPhone) {
        this.lName = lName;
        this.mName = mName;
        this.fName = fName;
        this.streetName = streetName;
        this.cityName = cityName;
        this.stateName = stateName;
        this.zipcode = zipcode;
        this.hPhone = hPhone;
        this.cPhone = cPhone;
    }



    /**
     *
     * @return
     */
    public String getCPhone() {
        return cPhone;
    }

    /**
     *
     * @return
     */
    public String getCityName() {
        return cityName;
    }

    /**
     *
     * @return
     */
    public String getFName() {
        return fName;
    }

    /**
     *
     * @return
     */
    public String getHPhone() {
        return hPhone;
    }

    /**
     * 
     * @return
     */
    public String getLName() {
        return lName;
    }

    /**
     *
     * @return
     */
    public String getMName() {
        return mName;
    }

    /**
     *
     * @return
     */
    public int getNumContacts() {
        return numContacts;
    }

    /**
     *
     * @return
     */
    public String getStateName() {
        return stateName;
    }

    /**
     *
     * @return
     */
    public String getStreetName() {
        return streetName;
    }

    /**
     *
     * @return
     */
    public String getZipcode() {
        return zipcode;
    }

    /**
     *
     * @param cPhone
     */
    public void setCPhone(String cPhone) {
        this.cPhone = cPhone;
    }

    /**
     *
     * @param cityName
     */
    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    /**
     *
     * @param fName
     */
    public void setFName(String fName) {
        this.fName = fName;
    }

    /**
     *
     * @param hPhone
     */
    public void setHPhone(String hPhone) {
        this.hPhone = hPhone;
    }

    /**
     *
     * @param lName
     */
    public void setLName(String lName) {
        this.lName = lName;
    }

    /**
     *
     * @param mName
     */
    public void setMName(String mName) {
        this.mName = mName;
    }

    /**
     *
     * @param numContacts
     */
    public void setNumContacts(int numContacts) {
        this.numContacts = numContacts;
    }

    /**
     *
     * @param stateName
     */
    public void setStateName(String stateName) {
        this.stateName = stateName;
    }

    /**
     *
     * @param streetName
     */
    public void setStreetName(String streetName) {
        this.streetName = streetName;
    }

    /**
     *
     * @param zipcode
     */
    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Person)) {
            return false;
        } else {
            Person person = (Person) obj;
            if (lName.equals(person.getLName())) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     *
     * @param person
     */
    public void addPerson(Person person) {
        numContacts += person.getNumContacts();
    }

    @Override
    public String toString() {
        return lName + "," + fName + " " + mName
                + " | " + streetName + ", " + cityName + ", " + stateName + " " + zipcode
                + " | Home Phone: " + hPhone
                + " | Mobile Phone: " + cPhone;
    }

}

Open in new window

the Friend Class
 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package P4.test;

import java.util.ArrayList;

/**
 *
 * @author gcurrier
 */
public class Friend extends Person {

    private ArrayList<ArrayList> contactList;
    private ArrayList contactItem;

    /**
     *
     */
    public Friend() {
        contactList = new ArrayList<ArrayList>();
        contactItem = new ArrayList();
    }

    /**
     *
     * @param index
     * @return
     */
    public Object getContactItem(int index) {
        return contactItem.get(index);
    }

    /**
     *
     * @param index
     * @return
     */
    public ArrayList getContactList(int index) {
        return contactList.get(index);
    }

    /**
     *
     * @return
     */
    public int getContactItemSize() {
        return contactItem.size();
    }

    /**
     *
     * @return
     */
    public int getContactListSize() {
        return contactList.size();
    }

    /**
     *
     * @param index
     * @return
     */
    public int getContactListObjectSize(int index) {
        int size = contactList.get(index).size();
        return size;
    }

    /**
     *
     * @param person
     */
    public void addContactItem(Person person) {
        if (contactItem.indexOf(person) > -1) {
            ArrayList newContact = new ArrayList<String>();
            for (int i = 0; i < contactItem.size(); i++) {
                Person person1 = (Person) contactItem.get(i);
                if (person1.equals(person)) {
                    person.addPerson(person);
                }
                newContact.add(person);
            }
            contactItem = newContact;
        } else {
            contactItem.add(person);
        }
    }

    /**
     *
     * @param index
     * @param contactItem
     */
    public void addContactList(int index, Object contactItem) {
        while (index >= contactList.size()) {
            contactList.add(new ArrayList());
        }
        contactList.get(index).add(getContactItem(index));
    }
}

Open in new window


The input file
 input.txt

From my perspective of lesser experience, it appears that everything is working (more or less) ok.  I just have the problem of "splitting" the tokens into individual objects so that each line is itself an ArrayList of objects which can be further added to the main ArrayList.  In other words, each string is itself added as an individual object and then, at the end of line of input text, a new array list is created (or a new ArrayList for each Person Object - something like that). I'm kind of lost at the moment and could use some advice on how to do this.  Explanations are good, adding examples to demonstrate the explanation would be great.  Also, I am quite sure I have not picked the best way to do what I am trying to do so if there is a better way (while keeping the classes - they're required), I'm all ears.
Thanks
ArrayListRun.java
Person.java
Friend.java
0
Comment
Question by:g_currier
  • 6
  • 4
  • 3
13 Comments
 
LVL 47

Expert Comment

by:for_yan
ID: 35150104
I'm not sure I can understand why you need to think of it as and "ArrayList for each Person Object".
The information in each line is just what is held in your Person object itself.
You just split your input line and run the constructor - create Person object corresponding to each line, then you can make ArrayList
of these Person objects.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 35150142
The first thing to recognise is that an address books (class AddressBook) is, or contains List<Address>
0
 

Author Comment

by:g_currier
ID: 35160587
As far as "each Person Object" is concerned, I use that terminology because the the return value of an array list is an object.  Maybe I'm confusing it...

In any case I need to be more specific: I'm supposed to be able to return any item within the inner array list (i.e. if I want to return only the first name it should look something like this:
this loop in the runner class
for (i=0;i<=clSize;i++){
                System.out.println(f.getContactIndex(i,2));
}

Open in new window


which is using this method in the Friend class:
public Object getContactIndex(int index1,int index2){
        return contactList.get(index1).get(index2);
    }

Open in new window

or something to that effect. I believe the reason it doesn't work is because the inner ArrayList contains only one object - each line (as a single string) from the input file.  This means that I am not adding a Person correctly.  I am just having trouble figuring out what needs to change, and that is where I could use the help.

this is the output from the running the above code
run:
Contact Item ArrayList size: 6
PERSON OBJECT : 
(contactItem - an ArrayList of Objects.)
-----------------------------------------------
Index 0: Smith,John P | abc 123rd ave, nowhere, NJ 12548 | Home Phone: (126)598-4580 | Mobile Phone: (321)650-9874 
Index 1: Public,John Q | 5th Ave w, smalltown, NC 97548 | Home Phone: (445)896-5023 | Mobile Phone: (326)551-4987 
Index 2: Nobody,Jane X | 123 abc st, Somewhere, OK 56986 | Home Phone: (654)613-2987 | Mobile Phone: (985)864-7123
Index 3: Smythe,Gordon P | def 133rd ave, hoboken, NJ 23562 | Home Phone: (125)487-4580 | Mobile Phone: (321)616-5974 
Index 4: Xavier,Chuck P | 3 Private dr., Westchester, NY 12548 | Home Phone: (659)228-4580 | Mobile Phone: (375)450-9874 
Index 5: Furball,Harry P | 2 Desert Rd, someplace sunny, NV 84521 | Home Phone: (800)867-5309 | Mobile Phone: (903)576-8008 


Contact List ArrayList size: 6
LIST OBJECT : 
(contactList - an ArrayList of ArrayLists)
-----------------------------------------------
Index 0: [Smith,John P | abc 123rd ave, nowhere, NJ 12548 | Home Phone: (126)598-4580 | Mobile Phone: (321)650-9874 ]
Index 1: [Public,John Q | 5th Ave w, smalltown, NC 97548 | Home Phone: (445)896-5023 | Mobile Phone: (326)551-4987 ]
Index 2: [Nobody,Jane X | 123 abc st, Somewhere, OK 56986 | Home Phone: (654)613-2987 | Mobile Phone: (985)864-7123]
Index 3: [Smythe,Gordon P | def 133rd ave, hoboken, NJ 23562 | Home Phone: (125)487-4580 | Mobile Phone: (321)616-5974 ]
Index 4: [Xavier,Chuck P | 3 Private dr., Westchester, NY 12548 | Home Phone: (659)228-4580 | Mobile Phone: (375)450-9874 ]
Index 5: [Furball,Harry P | 2 Desert Rd, someplace sunny, NV 84521 | Home Phone: (800)867-5309 | Mobile Phone: (903)576-8008 ]


Size of each ArrayList in contactList: 
-----------------------------------------------
Index 0 size : 1
Index 1 size : 1
Index 2 size : 1
Index 3 size : 1
Index 4 size : 1
Index 5 size : 1


Smith,John P | abc 123rd ave, nowhere, NJ 12548 | Home Phone: (126)598-4580 | Mobile Phone: (321)650-9874 
        java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)
        at java.util.ArrayList.get(ArrayList.java:322)
        at P4.test.ArrayListRun.<init>(ArrayListRun.java:85)
        at P4.test.ArrayListRun.main(ArrayListRun.java:22)
BUILD SUCCESSFUL (total time: 0 seconds)

Open in new window


I am reading the Collections API to learn more about Lists at the moment, but it's slow going.

Again, I appreciate any help I can get.

Thanks
0
 
LVL 47

Expert Comment

by:for_yan
ID: 35161145
So, what is wrong with it - I compiled it and ran
it and it ran fine.
I got the output below.
What should I do to get the error you are getting?

Contact Item ArrayList size: 6
PERSON OBJECT : 
(contactItem - an ArrayList of Objects.)
-----------------------------------------------
Index 0: Smith,John P | abc 123rd ave, nowhere, NJ 12548 | Home Phone: (126)598-4580 | Mobile Phone: (321)650-9874 
Index 1: Public,John Q | 5th Ave w, smalltown, NC 97548 | Home Phone: (445)896-5023 | Mobile Phone: (326)551-4987 
Index 2: Nobody,Jane X | 123 abc st, Somewhere, OK 56986 | Home Phone: (654)613-2987 | Mobile Phone: (985)864-7123
Index 3: Smythe,Gordon P | def 133rd ave, hoboken, NJ 23562 | Home Phone: (125)487-4580 | Mobile Phone: (321)616-5974 
Index 4: Xavier,Chuck P | 3 Private dr., Westchester, NY 12548 | Home Phone: (659)228-4580 | Mobile Phone: (375)450-9874 
Index 5: Furball,Harry P | 2 Desert Rd, someplace sunny, NV 84521 | Home Phone: (800)867-5309 | Mobile Phone: (903)576-8008 


Contact List ArrayList size: 6
LIST OBJECT : 
(contactList - an ArrayList of ArrayLists)
-----------------------------------------------
Index 0: [Smith,John P | abc 123rd ave, nowhere, NJ 12548 | Home Phone: (126)598-4580 | Mobile Phone: (321)650-9874 ]
Index 1: [Public,John Q | 5th Ave w, smalltown, NC 97548 | Home Phone: (445)896-5023 | Mobile Phone: (326)551-4987 ]
Index 2: [Nobody,Jane X | 123 abc st, Somewhere, OK 56986 | Home Phone: (654)613-2987 | Mobile Phone: (985)864-7123]
Index 3: [Smythe,Gordon P | def 133rd ave, hoboken, NJ 23562 | Home Phone: (125)487-4580 | Mobile Phone: (321)616-5974 ]
Index 4: [Xavier,Chuck P | 3 Private dr., Westchester, NY 12548 | Home Phone: (659)228-4580 | Mobile Phone: (375)450-9874 ]
Index 5: [Furball,Harry P | 2 Desert Rd, someplace sunny, NV 84521 | Home Phone: (800)867-5309 | Mobile Phone: (903)576-8008 ]


Size of each ArrayList in contactList: 
-----------------------------------------------
Index 0 size : 1
Index 1 size : 1
Index 2 size : 1
Index 3 size : 1
Index 4 size : 1
Index 5 size : 1

Process finished with exit code 0

Open in new window

0
 

Author Comment

by:g_currier
ID: 35161168
add this:
public Object getContactIndex(int index1,int index2){
               return contactList.get(index1).get(index2);
} 

Open in new window


to the Friend class

then add this
for (i=0;i<=clSize;i++){
                System.out.println(f.getContactIndex(i,2));
} 

Open in new window

to the runner class
0
 
LVL 47

Expert Comment

by:for_yan
ID: 35161455

Well, for each line you call once this method:
   f.addContactList(f.getContactItemSize()-1, f.getContactItem(i));

This method for each index will add just one element:
    contactList.get(index).add(getContactItem(index));

Then you in fact want to read the third element for each index:

System.out.println(f.getContactIndex(i,2));


Not surprisingly it reports array element out of bounds

If you make it

System.out.println(f.getContactIndex(i,0));

it will work, at least without error.

With all that it is hard to understand your logic.

If your goal is to have AddressBook - then why not to have just one
dimensional ArrayList of Person object
and implement all sorts of searches across this ArrayList.
With your design it is hard to follow the logic.

In a sense of AddressBook, who should be Friend, and why you need this object?
In the AddressBook there is a notion of a record, a person, of some elements
of person information, say, Address, Phone,  but  is there a notion of Friend in the AddressBook?









0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:g_currier
ID: 35161502
True.
I have already started rewriting things to make a little clearer and will post back later with what I have.
0
 
LVL 47

Accepted Solution

by:
for_yan earned 500 total points
ID: 35161543
Sure. I recommend not to use what you call two-dimensional ArrayLists - it
is hard to keep them in mind and have a good feeling of them (the same applies, by the way,
 to two-dimensional arrays; arrays are in general even less convenient; almost always is better to use
ArrayLists instead).
ArrayList and HashMap are most convenient collections.
In certain situations you may need to use HashMap which has ArrayList objects as values and
usually something simple like String or Integer (corresponding to integer key) objects as keys.
These kind of collections are easier to understand and manipulate in your mind.
I don't think you would need anything else to model all possible details of AddressBook.
0
 

Author Comment

by:g_currier
ID: 35161559
I have decided to use ArrayList<String> as it becomes very easy to add contact details.  I may end moving away from the guidelines of the project, but I intend to create something that at least works with a functional GUI to go with it (also required).
0
 

Author Closing Comment

by:g_currier
ID: 35161562
I will add differnet posts as I progress through this.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 35163376
If  "The project is to create an Address Book GUI without using arrays" then your design is over-complex. The task of an address book is to maintain a list of contacts, not to map the relations between individual contacts. The Friend class is thus unnecessary. 'Person' is also mistakenly named: a contact can be maintained for a company (i have several in my address book where i've no idea of any individual) and something like my original suggestion would be better, or 'Contact' if you prefer.

If the idea is to show the use of collections, then they are better employed in cases where multiplicity is evident in the Address/Contact class, e.g. where there are several phone numbers possible.
0
 

Author Comment

by:g_currier
ID: 35167999
I understand.  I have switched to using an ArrayList and I am also attempting the use of a sublist and a ListIterator.  I have also renamed the classes accordingly.  It might get a few points knocked off my grade (the specific names are requirements) but they were only confusing me anyway.  No matter, I will explain it in my analysis when I turn it in.  I still have to tie the methods to button actions in a GUI.

Thanks for the advice, I appreciate it.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 35171258
>>It might get a few points knocked off my grade (the specific names are requirements) but they were only confusing me anyway.

Well they confuse me too ;) That's a good plan
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now