• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 277
  • Last Modified:

Need Help Iterating through a List

I have finally gotten this project to an operable level and have need of some help in iterating through the ArrayList created.

I think I have a solution for iterating forward but it doesn't quite work right in that when the end of the list is reached it (of course) throws a NoSuchElement error.  I am unsure of what conditions need to be set so that the list starts back at the beginning.

Further I do not not know exactly how to iterate backwards through the list (as is demonstrated by the method BookActions.getPreviousContact().

The end result I am looking for is to be able to iterate through the list in both directions, from the index it is at currently.

Also, I would like to be able to delete that contact as well as perform a search to find any specific contact based on the last name.

I have included the files I am using, as well as input and output files.  The help file I am leaving out. AddressBook.java  AddressBookGUI.java ContactBook.java BookActions.java Person.java Friend.java Address.java input.txt loadFile.txt
output.txt
0
g_currier
Asked:
g_currier
  • 24
  • 18
1 Solution
 
CEHJCommented:
When doing this type of thing, it's usually better to keep an instance variable holding the current position, then use methods such as
public void previous() {
   currentIndex--;
   if (currentIndex < 0) {
        currentIndex = list.size() - 1;
   }
}


public void next() {
   currentIndex++;
   if (currentIndex == list.size()) {
        currentIndex = 0;
   }
}

Open in new window

0
 
g_currierAuthor Commented:
I thought that's what I was doing with the static int iterate and start?
0
 
g_currierAuthor Commented:
I'll work on it a bit.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
CEHJCommented:
>>I thought that's what I was doing with the static int iterate and start?

I didn't look, since i didn't know where to do so ;)
0
 
g_currierAuthor Commented:
Sorry, I put most of the methods that respond to button events in BookActions.  I know it isn't perfect, but I'm working on it. :-)
0
 
CEHJCommented:
An Iterator is not appropriate for your use case
0
 
g_currierAuthor Commented:
How do you mean?

I changed the methods a bit and it "kind of" works but not the way it should.

    public void getPreviousContact() {
        ListIterator itr = c.contactList.listIterator(iterate);
        String line = itr.previous().toString();
        try {
            Scanner scan = new Scanner(line);
            scan.useDelimiter(":");
            while (scan.hasNext() && (iterate != start)) {
                if (itr.hasPrevious()) {
                    abg.setLastName(scan.next());
                    abg.setFirstName(scan.next());
                    abg.setMiddleName(scan.next());
                    abg.setStreetName(scan.next());
                    abg.setCityName(scan.next());
                    abg.setStateName(scan.next());
                    abg.setZipCode(scan.next());
                    abg.setHomePhone(scan.next());
                    abg.setCellPhone(scan.next());
                    iterate--;
                } else {
                    abg.setHelpText("End of List reached.  Showing first contact in list");
                    iterate = 0;
                    getFirstContact();
                }
            }
            scan.close();
            abg.setHelpText("Size of list: " + getEnd() + "\nContact index number: " + iterate + "\n\n" + abg.toString());
        } catch (Exception e) {
            System.out.println(e + " in BookActions.getLastContact() method.");
            //e.printStackTrace();
        }
    }

    public void getNextContact() {
        ListIterator itr = c.contactList.listIterator(iterate);
        String line = itr.next().toString();
        try {
            Scanner scan = new Scanner(line);
            scan.useDelimiter(":");
            while (scan.hasNext() && (iterate != getEnd()-1)) {
                if (itr.hasNext()) {
                    abg.setLastName(scan.next());
                    abg.setFirstName(scan.next());
                    abg.setMiddleName(scan.next());
                    abg.setStreetName(scan.next());
                    abg.setCityName(scan.next());
                    abg.setStateName(scan.next());
                    abg.setZipCode(scan.next());
                    abg.setHomePhone(scan.next());
                    abg.setCellPhone(scan.next());
                    iterate++;
                } else {
                    abg.setHelpText("End of List reached.  Showing first contact in list");
                    iterate = 0;
                    getFirstContact();
                }
            }
            scan.close();
            abg.setHelpText("Size of list: " + getEnd() + "\nContact index number: " + iterate + "\n\n" + abg.toString());
        } catch (Exception e) {
            System.out.println(e + " in BookActions.getLastContact() method.");
            //e.printStackTrace();
        }
    }

Open in new window

0
 
CEHJCommented:
As i said, an Iterator/ListIterator  is not appropriate
0
 
CEHJCommented:
Not sure why you're using a Scanner either: why isn't the List holding  proper objects instead of strings?
0
 
g_currierAuthor Commented:
I think it's because they are being inserted in that fashion.  The ContactBook class has two methods that use a scanner to feed the List.  The reason I convert the objects to strings is for the purpose of using the delimiter in the input file. (I don't really know any other way).
0
 
CEHJCommented:
You should be forming objects out of an input file as early as possible and then they should remain (Contact) objects
0
 
g_currierAuthor Commented:
I am realizing that now.  Unfortunately, this project is due in two days and I don't think I know enough on my own to change all that is needed in time.

Incidently I tried to use a BufferedReader wrapping an InputStreamReader...that just confused the hell out of me.  I need the delimiter to separate the fields.  If they aren't strings, how else do I do it without using arrays? (e.g. the String[] needed for the substring() method)?

As I said above, I can only work with what I know and at least half understand. :-/
0
 
g_currierAuthor Commented:
As far as I can tell from what I have so far, in the BookActions.addContact() method, a friend object is passed as a parameter to the ContactBook.addToList() method

from here:
 
public void addContact() {
        int response;
        try {
            String lName = getTxtLastName();
            String mName = getTxtMiddleName();
            String fName = getTxtFirstName();
            String streetName = getTxtStreet();
            String cityName = getTxtCity();
            String stateName = getTxtState();
            String zipCode = getTxtZipCode();
            String hPhone = getTxtHomePhone();
            String cPhone = getTxtCellPhone();
            //CONSTRUCT OBJECTS
            address = new Address(streetName, cityName, stateName, zipCode);
            friend = new Friend(lName, fName, mName, streetName, cityName, stateName, zipCode, hPhone, cPhone);
            try {
                c.addToList(friend);
                c.setNumContacts();
                getLastContact();
                abg.setHelpText("Contact Added!\n" + abg.toString());
                //entry is added to end of list so, get the last entry and display it
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (getTxtLastName().isEmpty() && (getTxtHomePhone().isEmpty() || getTxtCellPhone().isEmpty())) {
                JOptionPane.showMessageDialog(newFrame,
                        "To add a contact you must at least add\n"
                        + "a Last Name and a Phone Number", "Empty Contact Entry Error",
                        JOptionPane.ERROR_MESSAGE);

            }
        } catch (NullPointerException npe) {
            System.out.println(npe + " while adding a contact in BookActions.addContact() method.");
            npe.printStackTrace();
        } catch (Exception e) {
            System.out.println("Error in BookActions.addContact().");
            e.printStackTrace();
        }
    }

Open in new window


to here:
 
public void addToList(Friend friend) {
        this.contactList.add(friend);
        setNumContacts();
    }

Open in new window


I was under the impression I was actually adding Objects to the ArrayList.  Is this not so?
0
 
g_currierAuthor Commented:
Just had a thought about it:

If I pass all the data fields as objects, shouldn't I be able to use the substring method to separate them and then LATER convert them to strings? I'm not sure if that is what you mean but it makes sense to me (unless i've got it all wrong)?
0
 
CEHJCommented:
You've made it awkard to parse the input file by not ensuring that each contact occupies its own line
0
 
g_currierAuthor Commented:
Can you explain?
0
 
CEHJCommented:
e.g.

Smythe:Gordon:P:def 133rd ave:hoboken:NJ:23562:(125)487-4580:(321)616-5974
0
 
g_currierAuthor Commented:
if by that you mean each set of data fields is on its own line in the input file, they are. I made sure of it by entering each on a separate line after a carriage return in the .txt file (Windows).  

Is that what you mean? if not, I'm sorry, I don't understand.
0
 
CEHJCommented:
In input.txt they stretch over 3 lines
0
 
g_currierAuthor Commented:
there must be a difference between our systems because even with the wordwrap off in notepad each occupies its own line as I see it.

I have included a screen shot of the file as displayed on screen for me screenshot
0
 
CEHJCommented:
On closer inspection, each address is separated by a carriage return / newline pair. But on my system, it picks up the fact that there are lone newline characters before the state and before the first phone numbers. This might not be a problem depending on how you're parsing it

The point is that the normal way to do this would be (for each contact)

Contact c = new Contact(line.split(":"));
0
 
g_currierAuthor Commented:
Well that at least explains this out put from this code:
public void viewAll() {
        int min = 0;
        List list = c.contactList.subList(0, c.getSize());
        int max = list.size();
        Object itr = null;
        String all = null;
        System.out.println(c.getNumContacts());
        System.out.println(max+"");
        for(int i = 0;i<=max-1;i++){
            itr = list.get(i);
             all = itr.toString();
             System.out.print(all);
        }
        
    }

Open in new window


output:
8
8
Last:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone
Smythe:Gordon:P:def 133rd ave:hoboken
:NJ:23562
:(125)487-4580:(321)616-5974
Xavier:Chuck:P:3 Private dr.:Westchester
:NY:12548
:(659)228-4580:(375)450-9874
Furball:Harry:P:2 Desert Rd:someplace sunny
:NV:84521
:(800)867-5309:(903)576-8008
brody:willy:f:123 xyz ave:Someplace
:NE:52387
:(186)345-2931:(325)457-4523
wright:danielle:g:123 abc st:lost
:WY:65986
:(284)342-2167:(967)856-7167
sane:Not:n:123 abc st:faraway
:KS:56039
:(853)567-9217:(165)456-7423
toothless:Ai:m:123 abc st:in the woods
:OR:91827
:(174)345-9021:(475)342-7321

Open in new window


Though I am not sure why...all of it was typed in
0
 
g_currierAuthor Commented:
so then something like this?
address = new Address(line.split(":",3));
person = new Person(line.split(":",2));
friend = new Friend(person,address,line.split(":",1));

Open in new window


given a line like this:
Last:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone

Open in new window

0
 
CEHJCommented:
That kind of thing
0
 
g_currierAuthor Commented:
OK,

I am trying to rebuild the constructors in each class without breaking anything too much (I'm running low on time and it's already after 1 a.m. here).  I'll post the new classes as soon as I have them mostly complete.
0
 
g_currierAuthor Commented:
here are the constructors (I think).  Would this be right?
 
public Person(String[] line){
        setLName(line[0]);
        setFName(line[1]);
        setMName(line[2]);
    }


    public Address(String[] line){
        setStreetName(line[0]);
        setCityName(line[1]);
        setStateName(line[2]);
        setZipCode(line[3]);
    }

public class Friend extends Person {

    public Object hPhone, cPhone;
    public Address a = new Address();

    public Friend() {
        super();
    }

    public Friend(String[] line) {
        super(line[0], line[1], line[2]);//no idea...this is incorrect 
    }

    public Friend(Object lName, Object fName, Object mName,
            Object streetName, Object cityName, Object stateName, Object zipCode,
Object hPhone, Object cPhone) {
        super(lName, fName, mName);
        a.setStreetName(streetName);
        a.setCityName(cityName);
        a.setStateName(stateName);
        a.setZipCode(zipCode);
        sethPhone(hPhone);
        setcPhone(cPhone);

    }

    public Friend(Object hPhone, Object cPhone) {
        sethPhone(hPhone);
        setcPhone(cPhone);
    }

Open in new window


The Friends class constructors are what I have no idea of.
0
 
CEHJCommented:
You wouldn't pass Object into the ctors. What's the difference between Friend and Person?
0
 
g_currierAuthor Commented:
only what I was told the difference was (in correspondence):
person has the name items, friend is whatever else (as an extension of person).
0
 
CEHJCommented:
The fields should largely be of type String except for stuff like Address
0
 
g_currierAuthor Commented:
So then how does the friend constructor need to change if I add an address as an object?
 
public Friend(String lName, String fName, String mName,
            String streetName, String cityName, String stateName, String zipCode, String hPhone, String cPhone) {
        super(lName, fName, mName);
        a.setStreetName(streetName);
        a.setCityName(cityName);
        a.setStateName(stateName);
        a.setZipCode(zipCode);
        sethPhone(hPhone);
        setcPhone(cPhone);

    }

Open in new window

0
 
CEHJCommented:
Well as you know, i don't think the basic design is correct, but in the terms of your current design this should work
public Friend(Person person, Address address) {
    this.person = person;
    this.address = address;
}

Open in new window

0
 
g_currierAuthor Commented:
Is that how the file should be read in?
 public void readFromFile(String file) throws FileNotFoundException {
        try {
            String inFile = file;
            Scanner scanner = new Scanner(new File(inFile));
            scanner.useDelimiter(System.getProperty("line.separator")); //(";");
            String line = scanner.next();
            while (scanner.hasNext()) {
                address = new Address(line.split(":", 3));
                person = new Person(line.split(":", 2));
                friend = new Friend(person, address, line.split(":", 1));
            }
            scanner.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ContactBook.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 
CEHJCommented:
If would split the whole line in one go and assign the appropriate elements. You can't use the two-arg split like that - it doesn't work cumulatively
0
 
g_currierAuthor Commented:
I've been looking through the API and I'm not sure where to find it.
How is the file itself parsed and separated into lines?
0
 
g_currierAuthor Commented:
A bufferedReader?
0
 
CEHJCommented:
There's nothing wrong with your basic approach in your last code extract, apart from issues in my last comments
0
 
g_currierAuthor Commented:
How about this?
public void readFromFile(String file) throws FileNotFoundException {
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();

//                addLine(scanner.next());
            address = new Address(line.split(":", 3));
            person = new Person(line.split(":", 2));
            friend = new Friend(person, address, line.split(":", 1));
            addToList(friend);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ContactBook.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 
CEHJCommented:
You changed what you needn't have done and didn't change what you needed to change
0
 
g_currierAuthor Commented:
I know...got your post after I pushed mine?  I think this is what you mean?
     public void readFromFile(String file) throws FileNotFoundException {
        try {
            String inFile = file;
            Scanner scanner = new Scanner(new File(inFile));
            scanner.useDelimiter(System.getProperty("line.separator")); //(";");
            String[] line = scanner.next().split(":");
            while (scanner.hasNext()) {
                address = new Address(line[3],line[4],line[5],line[6]);
                person = new Person(line[0],line[1],line[3]);
                friend = new Friend(person, address, line[7],line[8]);
            }
            scanner.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ContactBook.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 
CEHJCommented:
Very close. Try this version
public void readFromFile(String file) {
	try {
	    Scanner scanner = new Scanner(new File(file));
	    while (scanner.hasNextLine()) {
		String[] fields = scanner.nextLine().split(":");
		address = new Address(fields[3],fields[4],fields[5],fields[6]);
		person = new Person(fields[0],fields[1],fields[3]);
		friend = new Friend(person, address, fields[7],fields[8]);
	    }
	    scanner.close();
	} catch (IOException ex) {
	    Logger.getLogger(ContactBook.class.getName()).log(Level.SEVERE, null, ex);
	}
    }

Open in new window

0
 
g_currierAuthor Commented:
OK, this works for input and is much much simpler.

but the list isn't being created or anything added to it (which means my contructors in the Person, Friend, and Address classes are incorrectly built).  In this I could use the help as well, now that I am adding objects to friend instead of strings.

Person Class
package P4.v2_4;

public class Person{

    public String lName,fName,mName;

    public Person(){
    }

    public Person(Person person){

    }

    public Person(String lName, String fName, String mName) {
        setLName(lName);
        setFName(fName);
        setMName(mName);
    }

    public Person(String[] line){
        setLName(line[0]);
        setFName(line[1]);
        setMName(line[2]);
    }

    public String getFName() {
        return fName;
    }

    public String getLName() {
        return lName;
    }

    public String getMName() {
        return mName;
    }

    public void setFName(String fName) {
        this.fName = fName;
    }

    public void setLName(String lName) {
        this.lName = lName;
    }

    public void setMName(String mName) {
        this.mName = mName;
    }

    public String getPersonToString() {
        return lName + "," + fName + " " + mName+"\n";
    }

    @Override
    public String toString() {
        return lName + ":" + fName + ":" + mName;
    }
}

Open in new window


Friend Class

package P4.v2_4;

public class Friend extends Person {

    public Object hPhone, cPhone;
    public Address a = new Address();

    public Friend() {
        super();
    }

    public Friend(Person person, Address address){
        super(person);
        a.setAddress(address);
    }

    public Friend(String hPhone, String cPhone) {
        sethPhone(hPhone);
        setcPhone(cPhone);
    }

    public Friend(Person person, Address address, String hPhone, String cPhone) {
        super(person);
        a.setAddress(address);
        sethPhone(hPhone);
        setcPhone(cPhone);

    }

    public Object getAddress() {
        return a.getAddress();
    }

    public Object getcPhone() {
        return cPhone;
    }

    public void setcPhone(Object cPhone) {
        this.cPhone = cPhone;
    }

    public Object gethPhone() {
        return hPhone;
    }

    public void sethPhone(Object hPhone) {
        this.hPhone = hPhone;
    }

    public Friend getFriend() {
        return this;
    }

    public String getFriendToString() {
        return getPersonToString() + a.toString() + "Home: " + hPhone.toString() + "\n"
                + "Mobile:  " + cPhone.toString() + "\n";

    }

    @Override
    public String toString() {
        return lName + ":" + fName + ":" + mName + ":" + a.toString() + ":" + hPhone + ":" + cPhone;

    }
}

Open in new window


Address class
package P4.v2_4;

import java.util.ArrayList;

public class Address {

    public String streetName, cityName, stateName, zipCode;
    public String[] address;

    public Address() {
    }

    public Address(Address address) {
    }

    public Address(String streetName, String cityName, String stateName, String zipCode) {
        setStreetName(streetName);
        setCityName(cityName);
        setStateName(stateName);
        setZipCode(zipCode);
    }

//    public Address(String[] line){
//        setStreetName(line[0]);
//        setCityName(line[1]);
//        setStateName(line[2]);
//        setZipCode(line[3]);
//    }

    public Object getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public Object getStateName() {
        return stateName;
    }

    public void setStateName(String stateName) {
        this.stateName = stateName;
    }

    public Object getStreetName() {
        return streetName;
    }

    public void setStreetName(String streetName) {
        this.streetName = streetName;
    }

    public Object getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public String[] getAddress() {
        //return streetName+",\n"+cityName +", "+ stateName + zipCode+"";
        return address;
    }

    public void setAddress(String[] address) {
        this.address = address;

    }
    public void setAddress(Address address) {
        
    }

    @Override
    public String toString() {
        return streetName + ":" + cityName + ":" + stateName + ":" + zipCode;
    }
}

Open in new window


ContactBook class
package P4.v2_4;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ContactBook {

    ArrayList<Friend> contactList = new ArrayList<Friend>();
    static int numContacts;
    AddressBookGUI abg;
    Person person = new Person();
    Friend friend = new Friend();
    Address address = new Address();

    public ContactBook() {
    }

    public int getNumContacts() {
        return numContacts;
    }

    public int setNumContacts() {
        return this.numContacts = contactList.size();
    }

    public ArrayList<Friend> getList() {
        return contactList;
    }

    public Object getContact(int index) {
        return contactList.get(index);
    }
    public void removeContact(int index) {
        contactList.remove(index);
    }

    public void removeAllContacts() {
        contactList.clear();
    }

    public boolean isListEmpty() {
        return contactList.isEmpty();
    }

    public int getSize() {
        return contactList.size();
    }

    public boolean hasContact() {
        return contactList.isEmpty();
    }

    public void addToList(Friend friend) {
        this.contactList.add(friend);
        setNumContacts();
    }

    public void readFromFile(String file) throws FileNotFoundException {
        try {
            //Scanner scanner = new Scanner(new FileReader(file));
            Scanner scanner = new Scanner(new File(file));
            while (scanner.hasNextLine()) {
                String[] fields = scanner.nextLine().split(":");
//                String line = fields[0].toString()+", "+fields[1].toString()+" "+fields[2].toString()+"\n"+
//                        fields[3].toString()+", "+fields[4].toString()+", "+fields[5].toString()+" "+fields[6].toString()+"\n"+
//                        fields[7].toString()+" "+fields[8].toString()+"\n";
//                System.out.println(line);
                address = new Address(fields[3],fields[4],fields[5],fields[6]);
                person = new Person(fields[0],fields[1],fields[2]);
                friend = new Friend(person, address, fields[7],fields[8]);
            }
            scanner.close();
            //System.out.println(fields[0].toString());
            //addToList(friend);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ContactBook.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}//end ContactBook class

Open in new window


AddressBook class (runner)
package P4.v2_4;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AddressBook {

    public static void main(String[] args) {
        new AddressBookGUI();
//        ContactBook c = new ContactBook();
//        String file = "input.txt";
//        try {
//            c.readFromFile(file);
//        } catch (IOException ex) {
//            Logger.getLogger(AddressBook.class.getName()).log(Level.SEVERE, null, ex);
//        }
    }
}

Open in new window


input
Last:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone
Anderson:Robert:M.:19 AnyStreet:AnyCity:AnyTown:12345:(123)456-7890:(987)654-3210
MacLean:Jerry:A.:34th Ave West, #12:Brooklyn:NY:66978:(447)582-9943:(447)221-7735
LastName:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone
Macintosh:Jerry:A.:34th Ave West, #12:Brooklyn:NY:66978:(447)582-9943:(447)221-7735
LName:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone
Macgregor:Jerry:A.:34th Ave West, #12:Brooklyn:NY:66978:(447)582-9943:(447)221-7735
TestLast:First:MI:Street:City:State:ZipCode:HomePhone:CellPhone
Sherman:Jerry:A.:34th Ave West, #12:Brooklyn:NY:66978:(447)582-9943:(447)221-7735
Shrew:Lucretia:W.:44 inches underground:farmers field:KS:55768:none:none

Open in new window

0
 
g_currierAuthor Commented:
I am moving to a new topic for the constructors I have made changes and will post them there.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 24
  • 18
Tackle projects and never again get stuck behind a technical roadblock.
Join Now