简体   繁体   English

是否有一个字符串来映射谷歌收藏中的分割器

[英]is there a string to map splitter in google collections

I am looking for the opposite of map joiner in google collections. 我正在寻找谷歌收藏中地图木匠的反面。 is there something like this, and if not why? 有这样的东西,如果不是为什么?

EDIT: here is an example how I wish it would be: 编辑:这是一个我希望如何的例子:

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

EDIT: I opened a request and it was implemented. 编辑:我打开了一个请求 ,它已经实现。 will be available in guava R10. 将在番石榴R10中提供。

Here's a class Maps2 that provides a method 这是一个提供方法的Maps2

Map<String, String> mapSequence(String)

It also provides two overloaded methods where you can change the delimiters that are used a) between keys and values (default: = ) and b) between entries (default: , ). 它还提供了两个重载方法,您可以在这些方法中更改在键和值之间使用的分隔符(默认值: = )和b)在条目之间(默认值: , )。 Guava classes like Splitter and Iterables are used internally to do the work. SplitterIterables这样的Guava类在内部用于完成工作。 The returned map is a LinkedHashMap , so entry order is preserved. 返回的地图是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;
    }

}

Test code: 测试代码:

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

Output: 输出:

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

I think there no such a feature in guava. 我认为番石榴没有这样的特征。 For me the reason is that the entry String can have many formats, so that you have to create your own "parser" for your own format. 对我来说,原因是条目String可以有多种格式,因此您必须为自己的格式创建自己的“解析器”。 An (ugly) alternative could be this one, if you can modify the format of your entry 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);

It's quite trivial to roll your own: 滚动自己是非常简单的:

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

Not in guava. 不是番石榴。

But StringToMap can do this for you. 但是StringToMap可以为你做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM