سؤال

أرغب في تطبيق وظيفة إلى مجموعة Java، في هذه الحالة بالذات. هل هناك طريقة لطيفة للقيام بذلك؟ لدي خريطة وترغب في تشغيلها فقط () على جميع القيم في الخريطة والحصول على الخريطة تعكس التحديثات.

هل كانت مفيدة؟

المحلول

مع Java 8's Lambdas، هذا هو بطانة واحدة:

map.replaceAll((k, v) -> v.trim());

من أجل التاريخ، إليك نسخة بدون لامبدا:

public void trimValues(Map<?, String> map) {
  for (Map.Entry<?, String> e : map.entrySet()) {
    String val = e.getValue();
    if (val != null)
      e.setValue(val.trim());
  }
}

أو أكثر عموما:

interface Function<T> {
  T operate(T val);
}

public static <T> void replaceValues(Map<?, T> map, Function<T> f)
{
  for (Map.Entry<?, T> e : map.entrySet())
    e.setValue(f.operate(e.getValue()));
}

Util.replaceValues(myMap, new Function<String>() {
  public String operate(String val)
  {
    return (val == null) ? null : val.trim();
  }
});

نصائح أخرى

لا أعرف طريقة للقيام بذلك مع مكتبات JDK غير ردك المقبول، إلا أن مجموعات Google تتيح لك القيام بالشيء التالي، مع الفصول com.google.collect.Maps و com.google.common.base.Function:

Map<?,String> trimmedMap = Maps.transformValues(untrimmedMap, new Function<String, String>() {
  public String apply(String from) {
    if (from != null)
      return from.trim();
    return null;
  }
}

الفرق الأكبر في تلك الطريقة مع المرء المقترح هو أنه يوفر عرضا على الخريطة الأصلية، مما يعني أنه، في حين أنه دائما في مزامنة مع الخريطة الأصلية، apply يمكن استدعاء الأسلوب عدة مرات إذا كنت تلمع الخريطة قال بشدة.

مشابه Collections2.transform(Collection<F>,Function<F,T>) الطريقة موجودة للمجموعات.

ما إذا كان يمكنك تعديل مجموعتك في مكانك أو لا تعتمد على فئة الكائنات في المجموعة.

إذا كانت هذه الكائنات غير قابلة للتطبيق (ما هي الأوتار)، فلن تتمكن فقط من أخذ العناصر من المجموعة وتعديلها - بدلا من ذلك، ستحتاج إلى تكرارها عبر المجموعة، ثم استدعاء الوظيفة ذات الصلة، ثم ضع قيمة القيمة الناتجة.

قد تكون مبالغة بالنسبة لشيء مثل هذا، ولكن هناك عدد من المرافق الجيدة حقا لهذه الأنواع من المشاكل في مجموعات Apache Commons. مكتبة.

Map<String, String> map = new HashMap<String, String>(); 
map.put("key1", "a  ");
map.put("key2", " b ");
map.put("key3", "  c");

TransformedMap.decorateTransform(map, 
  TransformerUtils.nopTransformer(), 
  TransformerUtils.invokerTransformer("trim"));

أنا أوصي بشدة جاكرتا كوكبون كوكب من أورايلي.

انتهى بي الأمر باستخدام طفرة في إجابة @ erickson، متحورا إلى:

  • عودة جديدة Collection, ، لا تعديل في المكان
  • إرجاع Collectionق مع عناصر من النوع يساوي نوع العودة من Function
  • دعم رسم الخرائط على قيم خريطة أو عناصر القائمة

رمز:

public static interface Function<L, R> {
    L operate(R val);
}

public static <K, L, R> Map<K, L> map(Map<K, R> map, Function<L, R> f) {
    Map<K, L> retMap = new HashMap<K, L>();

    for (Map.Entry<K, R> e : map.entrySet()) retMap.put(e.getKey(), f.operate(e.getValue()));

    return retMap;
}

public static <L, R> List<L> map(List<R> list, Function<L, R> f) {
    List<L> retList = new ArrayList<L>();

    for (R e : list) retList.add(f.operate(e));

    return retList;
}

سيكون عليك التكرار من جميع الإدخالات وتقليم كل قيمة سلسلة. نظرا لأن السلسلة غير قابلة للتطبيق، فسيتعين عليك إعادة وضعها في الخريطة. قد يكون النهج الأفضل قص القيم عند وضعها في الخريطة.

لقد توصلت إلى فئة "mapper"

public static abstract class Mapper<FromClass, ToClass> {

    private Collection<FromClass> source;

    // Mapping methods
    public abstract ToClass map(FromClass source);

    // Constructors
    public Mapper(Collection<FromClass> source) {
        this.source = source;
    }   
    public Mapper(FromClass ... source) {
        this.source = Arrays.asList(source);
    }   

    // Apply map on every item
    public Collection<ToClass> apply() {
        ArrayList<ToClass> result = new ArrayList<ToClass>();
        for (FromClass item : this.source) {
            result.add(this.map(item));
        }
        return result;
    }
}

أن أستخدم مثل هذا:

Collection<Loader> loaders = new Mapper<File, Loader>(files) {
    @Override public Loader map(File source) {
        return new Loader(source);
    }           
}.apply();

يمكنك أيضا إلقاء نظرة على مجموعات Google

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top