есть ли строка для отображения сплиттера в коллекциях Google - PullRequest
6 голосов
/ 04 ноября 2010

Я ищу противоположность столяра карт в коллекциях Google.Есть ли что-то вроде этого, и если нет, то почему?

РЕДАКТИРОВАТЬ: вот пример, как я хотел бы это было:

Map<String,String> myMap = Splitter.on(",").keyValueSeparator("=").split("k1=v1,k2=v2");

РЕДАКТИРОВАТЬ: я открыл запрос и это было реализовано.будет доступен в гуаве R10.

Ответы [ 4 ]

5 голосов
/ 04 ноября 2010

Вот класс Maps2, который предоставляет метод

Map<String, String> mapSequence(String)

Он также предоставляет два перегруженных метода, в которых вы можете изменять используемые разделители а) между ключами и значениями (по умолчанию: =)и б) между записями (по умолчанию: ,).Классы гуавы, такие как Splitter и Iterables, используются внутри для выполнения работы.Возвращаемая карта - LinkedHashMap, поэтому порядок ввода сохраняется.

public final class Maps2{

    public static final String DEFAULT_ENTRY_DELIMITER = ",";
    public static final String DEFAULT_KEYVALUE_DELIMITER = "=";

    private Maps2(){}

    public static Map<String, String> mapSequence(final String sequence){
        return mapSequence(sequence, DEFAULT_KEYVALUE_DELIMITER);
    }

    public static Map<String, String> mapSequence(final String sequence,
        final String keyValueDelim){
        return mapSequence(sequence, keyValueDelim, DEFAULT_ENTRY_DELIMITER);
    }

    public static Map<String, String> mapSequence(final String sequence,
        final String keyValueDelim, final String entryDelim){

        final Splitter entrySplitter =    Splitter.on(entryDelim)
                                                  .trimResults();
        final Splitter keyValueSplitter = Splitter.on(keyValueDelim)
                                                  .trimResults();
        final Map<String, String> map = Maps.newLinkedHashMap();
        for(final String token : entrySplitter.split(sequence)){
            final String[] items =
                Iterables.newArray(
                    keyValueSplitter.split(token), String.class);
            if(items.length != 2){
                throw new IllegalArgumentException(
                   "Map String not well-formed");
            }
            map.put(items[0], items[1]);
        }
        return map;
    }

}

Тестовый код:

public static void main(final String[] args){
    // note the randomly spread whitespace in the test code,
    // also the last entry has no value.
    // using Splitter().trimResults() we can handle junk like that
    final Map<String, String> map = Maps2.mapSequence("k1=v1 ,k2=v2, k3 =");
    System.out.println(map);
}

Вывод:

{k1 = v1, k2 = v2, k3 =}

2 голосов
/ 04 ноября 2010

Я думаю, что нет такой функции в гуаве. Для меня причина в том, что строка String может иметь много форматов, поэтому вам нужно создать свой собственный «парсер» для вашего собственного формата. (Уродливой) альтернативой может быть такая, если вы можете изменить формат вашей строки ввода:

final String toSplit = "k1=v1" + getProperty("line.separator") + "k2=v2";
final Properties properties = new Properties();
properties.load(new ByteArrayInputStream(toSplit.getBytes(Charsets.UTF_8)));
Maps.fromProperties(properties);
1 голос
/ 04 ноября 2010

Не в гуаве.

Но StringToMap может сделать это за вас.

1 голос
/ 04 ноября 2010

Это довольно тривиально, бросить свой собственный:

// assumes that input is properly formed e.g. "k1=v1,k2=v2"
public Map<String, String> toMap(String input) {
    Map<String, String> map = new HashMap<String, String>();
    String[] array = input.split(",");
    for (String str : array) {
        String[] pair = str.split("=");
        map.put(pair[0], pair[1]);
    }
    return map;
}
...