Статьи

Фильтрация и преобразование коллекций Java с коллекциями Guava2

Одним из удобств Groovy является возможность легко выполнять операции фильтрации и преобразования коллекций с помощью поддержки закрытия Groovy . Guava приносит фильтрацию и преобразование коллекций в стандартную Java, и это тема этого поста.

Класс Collections2 в Guava содержит два открытых метода, оба из которых являются статическими. Методы filter (Collection, Predicate) и transform (Collection, Function) делают то, что подразумевают их имена: выполняют фильтрацию и преобразование соответственно для данной коллекции. Коллекция, подлежащая фильтрации или преобразованию, является первым параметром для каждого статического метода. Второй аргумент фильтрующей функции — это экземпляр класса Predicate в Guava . Второй аргумент функции преобразования — это экземпляр класса Function Гуавы. Оставшаяся часть этого поста демонстрирует объединение всего этого для фильтрации и преобразования коллекций Java.

Фильтрация коллекций с помощью Guava

Фильтрация коллекций с помощью Guava довольно проста. Следующий фрагмент кода демонстрирует простой пример этого. Предоставляется набор строк (не показанный во фрагменте кода, но очевидный в выходных данных, следующих за кодом), и этот предоставленный набор фильтруется только для записей, начинающихся с заглавной буквы «J». Это делается с помощью поддержки регулярных выражений Java и Predicates.containsPattern (String) в Guava , но есть и другие типы предикатов, которые можно указывать.

Фильтрация строк, начинающихся с ‘J’

   /**
    * Demonstrate Guava's Collections2.filter method. Filter String beginning 
    * with letter 'J'.
    */
   public static void demonstrateFilter()
   {
      printHeader("Collections2.filter(Collection,Predicate): 'J' Languages");
      final Set<String> strings = buildSetStrings();
      out.println("\nOriginal Strings (pre-filter):\n\t" + strings);
      final Collection<String> filteredStrings =
              Collections2.filter(strings, Predicates.containsPattern("^J"));
      out.println("\nFiltered Strings:\n\t" + filteredStrings);
      out.println("\nOriginal Strings (post-filter):\n\t" + strings);
   }

Результат выполнения вышеуказанного метода показан ниже. Эти выходные данные показывают длинный список языков программирования, которые составляют исходный набор строк, возвращаемый buildSetStrings () [исходный код показан ниже в посте], и показывают результаты вызова фильтра, показывающие только те языки программирования, которые начинаются с ‘J. ‘

Преобразование коллекций с гуавой

Преобразование коллекций с помощью Guava работает аналогично синтаксической фильтрации, но функция используется для указания того, как записи исходной коллекции «преобразуются» в выходную коллекцию, а не с помощью предиката, чтобы определить, какие записи следует сохранить. Следующий фрагмент кода демонстрирует преобразование записей в данной коллекции в их верхнюю версию.

Преобразование записей в верхний регистр

   /**
    * Demonstrate Guava's Collections2.transform method. Transform input
    * collection's entries to uppercase form.
    */
   public static void demonstrateTransform()
   {
      printHeader("Collections2.transform(Collection,Function): Uppercase");
      final Set<String> strings = buildSetStrings();
      out.println("\nOriginal Strings (pre-transform):\n\t" + strings);
      final Collection<String> transformedStrings = 
              Collections2.transform(strings, new UpperCaseFunction<string, string="">());
      out.println("\nTransformed Strings:\n\t" + transformedStrings);
      out.println("\nOriginal Strings (post-transform):\n\t" + strings);
   }

В приведенном выше фрагменте кода преобразования используется класс UpperCaseFunction, но вы не найдете этого класса в документации по API Guava . Это пользовательский класс, определенный как показано в следующем листинге кода.

UpperCaseFunction.java

package dustin.examples;

import com.google.common.base.Function;

/**
 * Simple Guava Function that converts provided object's toString() representation
 * to upper case.
 * 
 * @author Dustin
 */
public class UpperCaseFunction<F, T> implements Function<F, T>
{
   @Override
   public Object apply(Object f)
   {
      return f.toString().toUpperCase();
   }
}

Результат запуска фрагмента кода преобразования, использующего класс UpperCaseFunction, показан далее.

В приведенных выше фрагментах кода показаны методы, предназначенные для фильтрации и преобразования записей коллекций с помощью Guava. Полный листинг кода для основного класса показан далее.

GuavaCollections2.java

package dustin.examples;

import static java.lang.System.out;

import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Class whose sole reason for existence is to demonstrate Guava's Collections2
 * class.
 * 
 * @author Dustin
 */
public class GuavaCollections2
{
   /**
    * Provides a Set of Strings.
    * 
    * @return Set of strings representing some programming languages.
    */
   private static Set<String> buildSetStrings()
   {
      final Set<String> strings = new HashSet<String>();
      strings.add("Java");
      strings.add("Groovy");
      strings.add("Jython");
      strings.add("JRuby");
      strings.add("Python");
      strings.add("Ruby");
      strings.add("Perl");
      strings.add("C");
      strings.add("C++");
      strings.add("C#");
      strings.add("Pascal");
      strings.add("Fortran");
      strings.add("Cobol");
      strings.add("Scala");
      strings.add("Clojure");
      strings.add("Basic");
      strings.add("PHP");
      strings.add("Flex/ActionScript");
      strings.add("JOVIAL");
      return strings;
   }

   /**
    * Demonstrate Guava's Collections2.filter method. Filter String beginning 
    * with letter 'J'.
    */
   public static void demonstrateFilter()
   {
      printHeader("Collections2.filter(Collection,Predicate): 'J' Languages");
      final Set<String> strings = buildSetStrings();
      out.println("\nOriginal Strings (pre-filter):\n\t" + strings);
      final Collection<String> filteredStrings =
              Collections2.filter(strings, Predicates.containsPattern("^J"));
      out.println("\nFiltered Strings:\n\t" + filteredStrings);
      out.println("\nOriginal Strings (post-filter):\n\t" + strings);
   }

   /**
    * Demonstrate Guava's Collections2.transform method. Transform input
    * collection's entries to uppercase form.
    */
   public static void demonstrateTransform()
   {
      printHeader("Collections2.transform(Collection,Function): Uppercase");
      final Set<String> strings = buildSetStrings();
      out.println("\nOriginal Strings (pre-transform):\n\t" + strings);
      final Collection<String> transformedStrings = 
              Collections2.transform(strings, new UpperCaseFunction<String, String>());
      out.println("\nTransformed Strings:\n\t" + transformedStrings);
      out.println("\nOriginal Strings (post-transform):\n\t" + strings);
   }

   /**
    * Print a separation header including the provided text.
    * 
    * @param headerText Text to be included in separation header.
    */
   private static void printHeader(final String headerText)
   {
      out.println("\n==========================================================");
      out.println("== " + headerText);
      out.println("==========================================================");
   }

   /**
    * Main function for demonstrating Guava's Collections2 class.
    * 
    * @param arguments 
    */
   public static void main(final String[] arguments)
   {
      demonstrateFilter();
      demonstrateTransform();
   }
}

Прежде чем завершить этот пост, следует обратить внимание на один важный момент. Оба метода, определенные в классе Collections2, содержат предупреждения в документации Javadoc об их использовании. Оба метода предоставляют коллекции, которые считаются «живыми представлениями» исходных коллекций и, таким образом, «изменения одного влияют на другое». Например, удаление элемента из исходной коллекции аналогичным образом удаляет его из преобразованной коллекции. Документация для каждого метода также предупреждает, что ни одна из них не возвращает коллекцию, которая является Сериализуемой или поточно-ориентированной, даже если исходная коллекция была Сериализуемой и / или поточно-ориентированной.

Вывод

Guava упрощает фильтрацию коллекций и преобразование записей коллекций в Java. Хотя этот код может быть не таким лаконичным, как в Groovy, для создания похожих вещей, он лучше, чем написание простого Java-кода без использования класса Collections2 в Guava. Коллекции Java могут быть отфильтрованы с помощью Collections2.filter (Коллекция, Предикат) или преобразованы с помощью Collections2.transform (Коллекция, Функция).

 

От http://marxsoftware.blogspot.com/2011/10/filtering-and-transforming-java.html