Java: Есть ли более простой способ для выделения элементов массива из строки? - PullRequest
2 голосов
/ 29 октября 2009

В приложении есть строка в следующем формате:

String elements = "[11, Джон,] [23, Адам,] [88, Энджи,] ..." (... означает, что в строке больше элементов)

Из заданной строки мне нужно создать ArrayList для идентификаторов имен (11, 23, 88, ...) и ArrayList для имен (Джон, Адам, Энджи, ...)

Я создал два метода:

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;
}

и намереваемся использовать эти два метода в методе parseArrayString (String inputString), который я еще не написал, но который будет работать следующим образом:

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);
        }

    }

Буду признателен, если кто-нибудь из вас предложит какой-нибудь более простой способ создания двух списков ArrayList из заданной строки.

Спасибо!

Ответы [ 6 ]

7 голосов
/ 29 октября 2009

Я бы предложил использовать регулярное выражение, захватив нужные элементы с помощью групп. В приведенном ниже примере создается список Person объектов вместо отдельных списков String s - инкапсуляция данных, как предлагали другие авторы:

    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);
    }

И простой класс для инкапсуляции данных:

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...
}
3 голосов
/ 29 октября 2009

Два ArrayLists? Я думаю, что вам нужен один список, содержащий объект типа Item с атрибутами id и name.

Если вы анализируете идентификатор и имя по отдельности, не заключая их в очевидный объект, вы не мыслите с точки зрения объектов.

1 голос
/ 21 октября 2012

Я сделал что-то немного проще:

String str = "   [ 1 , 2 ]   ";
str = str.trim();
String[] strArgs = str.substring(1, str.length() - 1).trim().split("\\s*,\\s*");
0 голосов
/ 29 октября 2009

Тест включен! ;)

    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);
    }
0 голосов
/ 29 октября 2009

Вот упрощенный пример:

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);

Даффимо прав, хотя о лучшем дизайне ОО.

0 голосов
/ 29 октября 2009

Что-то вроде:

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()));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...