0

I have a text file:

John Smith 2009-11-04
Jenny Doe 2009-12-29
Alice Jones 2009-01-03
Bob Candice 2009-01-04
Carol Heart 2009-01-07
Carlos Diaz 2009-01-10
Charlie Brown 2009-01-14

I'm trying to remove the dashes and store them as separate types: first, last, year,month,day and then add it to a sortedset/hashmap. But for some reason. It's not working right.

Here is my code:

public class Test {

    File file;
    private Scanner sc;
    //HashMap<Name, Date> hashmap = new HashMap<>();

    /**
     * @param filename
     */
    public Test(String filename) {
        file = new File(filename);
    }

    public void openFile(String filename) {
        // open the file for scanning
        System.out.println("Test file " + filename + "\n");
        try {
            sc = new Scanner(new File("birthdays.dat"));
        } 
        catch(Exception e) {
            System.out.println("Birthdays: Unable to open data file");
        }
    }

    public void readFile() {
        System.out.println("Name              Birthday");
        System.out.println("----              --------");
        System.out.println("----              --------");

        while (sc.hasNext()) {
            String line = sc.nextLine();
            String[] split = line.split("[ ]?-[ ]?");

            String first = split[0];
            String last = split[1];
            //int year = Integer.parseInt(split[2]);
            //int month = Integer.parseInt(split[3]);
            //int day = Integer.parseInt(split[4]);

                    Resource name = new Name(first, last);
                    System.out.println(first + " " + last + " " + split[2]  );
            //hashmap.add(name);

        }

    }

    public void closeFile() {
        sc.close();
    }

    public static void main(String[] args) throws FileNotFoundException,
            ArrayIndexOutOfBoundsException {
        try {
            Scanner sc = new Scanner( new File(args[0]) );

                for( int i = 0; i < args.length; i++ ) {
                    //System.out.println( args[i] );

                    if( args.length == 0 ) {

                    }
                    else if( args.length >= 1 ) {

                    }
                //  System.out.printf( "Name %-20s Birthday", name.toString(), date.toString() );
                }

        } catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("Usage: Birthdays dataFile");
            // Terminate the program here somehow, or see below.
            System.exit(-1);
        } catch (FileNotFoundException e) {
            System.err.println("Birthdays: Unable to open data file");
            // Terminate the program here somehow, or see below.
            System.exit(-1);
        }   

        Test r = new Test(args[0]);
        r.openFile(args[0]);
        r.readFile();
        r.closeFile();
    }
}
1
  • Your regex for the splitting makes no sense, because the structure of the text file is different. Use this instead: line.split("[ -]+") (or just line.split("[ -]") without the + sign). Commented Jan 31, 2015 at 9:41

5 Answers 5

1

Your splitting on dashes but your is program is build around a split using spaces.

Try just splitting on spaces

String[] split = line.split("\\s");

So "John Smith 2009-11-04".split("[ ]?-[ ]?"); results in ["John Smith 2009", "11", "04"] When what you want is for it to split on spaces ["John", "Smith", "2009-11-04"]

Sign up to request clarification or add additional context in comments.

Comments

1

I would do this differently, first create a domain object:

public class Person {
    private String firstName;
    private String lastName;
    private LocalDate date;

    //getters & setters

    //equals & hashCode

    //toString
}

Now create a method that parses a single String of the format you have to a Person:

//instance variable
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

public Person parsePerson(final String input) {        
    final String[] data = input.split("\\s+");
    final Person person = new Person();
    person.setFirstName(data[0]);
    person.setLastName(data[1]);
    person.setDate(LocalDate.parse(data[2], dateTimeFormatter));
    return person;
}

Note that the DateTimeFormatter is an instance variable, this is for speed. You should also set the ZoneInfo on the formatter if you need to parse dates not in your current locale.

Now, you can read your file into a List<Person> very easily:

public List<Person> readFromFile(final Path path) throws IOException {
    try (final Stream<String> lines = Files.lines(path)) {
        return lines
                .map(this::parsePerson)
                .collect(toList());
    }
}

And now that you have a List<Person>, you can sort or process them however you want.

You can even do this while creating the List:

public List<Person> readFromFile(final Path path) throws IOException {
    try (final Stream<String> lines = Files.lines(path)) {
        return lines
                .map(this::parsePerson)
                .sorted(comparing(Person::getLastName).thenComparing(Person::getFirstName))
                .collect(toList());
    }
}

Or have your Person implements Comparable<Person> and simply use natural order.

TL;DR: Use Objects for your objects and life becomes much simpler.

6 Comments

Could you explain more about public List<Person> readFromFile(final Path path) throws IOException { try (final Stream<String> lines = Files.lines(path)) { return lines .map(this::parsePerson) .sorted(comparing(Person::getLastName).thenComparing(Person::getFirstName)) .collect(toList()); } }
@AlFord what do you mean by explain more?
I have this but it does not works: private List<Person> name = new ArrayList<Person>(); public List<Person> readFromFile(final Path path) throws IOException { try (final Stream<String> lines = Files.lines(path)) { return lines .map(this::readFromFile) .sorted(comparing(Person::getLastName).thenComparing(Person::getFirstName)) .collect(toList()); } } private Object toList() { return null; }
@AlFord can you read that block of code you just added to the comments? I certainly can't. Also "does not work" is utterly unhelpful is diagnosing the problem. Post a new question if you wish.
@AlFord what is private Object toList() { return null; } ?? This should be an import static from Collectors.toList!
|
0

I would use a regex:

private static Pattern LINE_PATTERN
        = Pattern.compile("(.+) (.+) ([0-9]{4})-([0-9]{2})-([0-9]{2})");

...

    while (sc.hasNext()) {
        String line = sc.nextLine();
        Matcher matcher = LINE_PATTERN.matcher(line);
        if (!matcher.matches()) {
            // malformed line
        } else {
            String first = matcher.group(1);
            String last = matcher.group(2);
            int year = Integer.parseInt(matcher.group(3));
            int month = Integer.parseInt(matcher.group(4));
            int day = Integer.parseInt(matcher.group(5));
            // do something with it
        }
    }

Comments

0

You are splitting on spaces and a hyphen. This pattern does not exist.

    String[] split = line.split("[ ]?");

    String first = split[0];
    String last = split[1];

    line = split[2];
    //now split the date 
    String[] splitz = line.split("-");

or something like this might work:

     String delims = "[ -]+";
     String[] tokens = line.split(delims);

Comments

0

If i understood your question right then Here is answer. Check it out.

  List<String> listGet = new ArrayList<String>();
    String getVal = "John Smith 2009-11-04";
    String[] splited = getVal.split("[\\-:\\s]");
    for(int j=0;j<splited.length;j++)
    {
        listGet.add(splited[j]);

    }
    System.out.println("first name :"+listGet.get(0));
    System.out.println("Last name :"+listGet.get(1));
    System.out.println("year is :"+listGet.get(2));
    System.out.println("month is :"+listGet.get(3));
    System.out.println("day is :"+listGet.get(4));

OP :

first name :John
Last name :Smith
year is :2009
month is :11
day is :04

2 Comments

I tried this with a text file but it repeatedly loop through John Smith. Then, it gives error saying no line found.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.