views:

294

answers:

5

Hi,

In the application there is a string in the following format:

String elements = "[11, john,][23, Adam,][88, Angie,]..." (... means there are more elements in the string)

From the given string I have to create an ArrayList for name IDs (11, 23, 88, ...) and ArrayList for names (john, Adam, Angie, ...)

I created two methods:

private int getItemID(int listLocation, String inputString){
    int indexBeginning = inputString.indexOf("[", listLocation) + 1;
    int indexEnd = inputString.indexOf(",", listLocation) - 1;
    String sID = inputString.substring(indexBeginning, indexEnd);
    int result = Integer.parseInt(sID);
    return result;
}

private String getItemName(int listLocation, String inputString){
    int indexBeginning = inputString.indexOf(" ", listLocation) + 1;
    int indexEnd = inputString.indexOf(",", indexBeginning) - 1;
    String result = inputString.substring(indexBeginning, indexEnd);
    return result;
}

and intend to use these two methods in the method parseArrayString(String inputString), which I haven't written yet but would work the following way:

private void parseCommunityList(String inputString){
        int currentLocation = 0;
        int itemsCount = count the number of "[" characters in the string
        for(int i = 0; i < itemsCount; i++)
        {
               currentLocation = get the location of the (i)th character "[" in the string;
               String name = getItemName(currentLocation, inputString);
               int ID = getItemID(currentLocation, inputString);
               nameArray.Add(name);
               idArray,Add(ID);
        }

    }

I would appreciate if anyone of you could suggest any simpler way to create two ArrayLists from the given string.

Thanks!

+3  A: 

Two ArrayLists? I think you need one List containing object type Item with id and name attributes.

If you parse id and name individually, without encapsulating them into an obvious object, you aren't thinking in terms of objects.

duffymo
I agree, even though this does not really answer the question.
Daniel Schneller
A classical case of the Object Denial antipattern.
Joachim Sauer
+5  A: 

I would suggest using a regular expression, capturing the elements you want using groups. The example below creates a list of Person objects instead of individual lists of Strings - encapsulating the data as other posters have suggested:

    List<Person> people = new ArrayList<Person>();

    String regexpStr = "(\\[([0-9]+),\\s*([0-9a-zA-Z]+),\\])";
    String inputData = "[11, john,][23, Adam,][88, Angie,]";

    Pattern regexp = Pattern.compile(regexpStr);
    Matcher matcher = regexp.matcher(inputData);
    while (matcher.find()) {
        MatchResult result = matcher.toMatchResult();

        String id = result.group(2);
        String name = result.group(3);

        Person person = new Person(Long.valueOf(id), name);
        people.add(person);
    }

And a simple class to encapsulate the data:

public class Person {
    private Long id;
    private String name;

    public Person(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    // TODO equals, toString, hashcode...
}
teabot
A: 

Something like:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IdNamePairs {

    private List<Integer> ids = new ArrayList<Integer>();
    private List<String> names = new ArrayList<String>();

    public IdNamePairs(String string) {
     Pattern p = Pattern.compile("\\[([^\\]]+)\\]");
     Matcher m = p.matcher(string);
     while (m.find()) {
      String tuple = m.group(1);
      String[] idName = tuple.split(",\\s*");
      ids.add(Integer.valueOf(idName[0]));
      names.add(idName[1]);
     }
    }

    public List<Integer> getIds() {
     return Collections.unmodifiableList(ids);
    }

    public List<String> getNames() {
     return Collections.unmodifiableList(names);
    }

    public static void main(String[] args) {
     String str = "[11, john,][23, Adam,][88, Angie,]";
     IdNamePairs idNamePairs = new IdNamePairs(str);
     System.out.println(Arrays.toString(idNamePairs.getIds().toArray()));
     System.out.println(Arrays.toString(idNamePairs.getNames().toArray()));
    }
}
toolkit
A: 

Here's a simplified example:

List<String> nameArray = new ArrayList<String>();
List<String> idArray = new ArrayList<String>();
String input = "[11, john,][23, Adam,][88, Angie,]";
String[] pairs = input.split("((\\]\\[)|\\[|\\])");

for (String pair : pairs) {
 if (pair.length() > 0) {
  String[] elems = pair.split(", *");

  idArray.add(elems[0]);
  nameArray.add(elems[1]);
 }
}

System.out.println("IDs: " + idArray);
System.out.println("Names: " + nameArray);

duffymo is right though, about a better OO design.

Jack Leow
A: 

Test included! ;)

    class Entry {
     final int number;
     final String name;
     public Entry(int number, String name) {
      this.number = number;
      this.name = name;
     }
     @Override
     public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((name == null) ? 0 : name.hashCode());
      result = prime * result + number;
      return result;
     }
     @Override
     public String toString() {
      return "Entry [name=" + name + ", number=" + number + "]";
     }
     @Override
     public boolean equals(Object obj) {
      if (this == obj)
       return true;
      if (obj == null)
       return false;
      if (getClass() != obj.getClass())
       return false;
      Entry other = (Entry) obj;
      if (name == null) {
       if (other.name != null)
        return false;
      } else if (!name.equals(other.name))
       return false;
      if (number != other.number)
       return false;
      return true;
     }
    }

    class ElementsSplitter {

     public List<Entry> split(String elements) {
      List<Entry> entries = new ArrayList();
      Pattern p = Pattern.compile("\\[(\\d+),\\s*(\\w+),\\]");
      Matcher m = p.matcher(elements);
      while (m.find()) {
       entries.add(new Entry(Integer.parseInt(m.group(1)), m.group(2)));
      }
      return entries;
     }

    }

    @Test
    public void testElementsSplitter() throws Exception {
     String elementsString = "[11, john,][23, Adam,][88, Angie,]";
     ElementsSplitter eSplitter = new ElementsSplitter();
     List<Entry> actual = eSplitter.split(elementsString);
     List<Entry> expected = Arrays.asList(
       new Entry(11, "john"),
       new Entry(23, "Adam"),
       new Entry(88, "Angie"));
     assertEquals(3, actual.size());
     assertEquals(expected, actual);
    }
michael.kebe