2010-11-04 25 views
6

Je cherche le contraire de la carte joiner dans les collections google. Y at-il quelque chose comme ça, et sinon pourquoi?est-il une chaîne pour mapper splitter dans google collections

EDIT: voici un exemple que je souhaite que ce serait:

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

EDIT: Je ouvert un request et il a été mis en œuvre. sera disponible en goyave R10.

+0

Vous voulez analyser une chaîne à une carte? Et s'il vous plaît, ajoutez l'étiquette de goyave –

Répondre

2

Je pense qu'il n'y a pas une telle fonctionnalité dans la goyave. Pour moi, la raison en est que l'entrée String peut avoir plusieurs formats, de sorte que vous devez créer votre propre "analyseur" pour votre propre format. Un (laid) alternative pourrait être celle-ci, si vous pouvez modifier le format de votre chaîne d'entrée:

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

mais le problème d'analyse était déjà ciblé par le séparateur – oshai

+0

Oui, mais le Splitter n'est pas SplitterAndMapMaker. Avec votre "keyValueSeparator", ce n'est plus un Splitter. En tout cas, vous pouvez poster une demande sur http://code.google.com/p/guava-libraries/issues/list et attendre les réponses de goyaves. –

+0

+1 pour le lien – oshai

1

Il est tout à fait banal de rouler votre propre:

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

est ici une classe Maps2 qui fournit une méthode

Map<String, String> mapSequence(String) 

Il fournit également deux méthodes surchargées où vous pouvez modifier les délimiteurs utilisés a) entre les touches et les valeurs (par défaut: =) et b) entre les entrées (par défaut: ,). Les classes de goyave comme Splitter et Iterables sont utilisées en interne pour faire le travail. La carte renvoyée est un LinkedHashMap, de sorte que l'ordre d'entrée est conservé.

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

} 

Code d'essai:

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

Sortie:

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

+0

& @Peter Knego - vos deux solutions ne permettent pas de valeur avec un signe égal (par exemple "k1 = v1 = s, k2 = v2"). Au lieu d'utiliser un second séparateur, vous devez utiliser la fonction String.split avec l'argument limit token.split (keyValueDelim, 2); (BTW: je n'autorise pas la virgule en valeur :)) – ekeren

+1

Je ne suis pas d'accord, cela conduirait à des résultats imprévisibles et peu fiables (et si le = est dans la clé, pas la valeur?). Je pense qu'il est préférable d'échouer rapidement, et non: une simple fonction comme celle-ci ne peut pas cartographier des chaînes très complexes. Utilisez JSON si vous voulez plus de complexité. –

+0

vous m'avez facilement convaincu – ekeren