2017-01-12 3 views
1

Я пытался реализовать функционально аналогичен CollectionUtils transform (Apache Commons Collections)преобразования коллекции <myClass> в коллекции <String>

class CollectionUtils { 

    public static void transformerModifier(Collection<MyClass> myCollection) { 
     // How should I implement this method in order that 
     // output from the line 1 and line 2 will be the same ? 
    } 

    public static List<String> transform(Collection<MyClass> myCollection) { 
     List<String> strCollection = new LinkedList<>(); 
     for (MyClass item : myCollection) { 
      strCollection.add(item.getName()); 
     } 
     return strCollection; 
    } 
} 

class myClass { 
    private String name; 
    private int value; 

    myClass(String name, int value) { 
     this.name = name ; 
     this.value = value; 
    } 

    public String toString(){ 
     return new String(name+ ":" + value) ; 
    } 
} 

class MyClassCollection{ 
    private List<myClass> list ; 

    myClassCollection(List<myClass> list){ 
     this.list = list; 
    } 

    List<myClass> collection(){ 
     return list.clone(); 
    } 

} 

public class TestClass{ 

    public static void main (String[] args) { 

     List<MyClass> list = new ArrayList<>(); 
     list.add(new myClass("John", 12); 
     list.add(new myClass("Mike", 16); 
     list.add(new myClass("Eric", 13); 
     list.add(new myClass("Mark", 142); 
     list.add(new myClass("Alex", 112); 

     MyClassCollection myOjb = new MyClassCollection(list); 
     CollectionUtils.transformerModifier(myObj.collection()); 
     List<MyClass> myList = CollectionUtils.transform(myObj.collection()); 
     System.out.println(Arrays.toString(myObj.collection().toArray)); // line 1 
     System.out.println(Arrays.toString(myList.toArray));   // line 2 
    } 

} 

output: [John,Mike,Eric,Mark,Alex] // output after line 1 
output: [John,Mike,Eric,Mark,Alex] // should be output after line 2 

Мой вопрос можно ли реализовать метод transformerModifier в способе, которым он изменит коллекцию объекта myObj так что myObj.collection() возвращают не List<myClass> но список List<String> (где строка - это данные от private String name данные члена myClass)?

Я предполагаю, что решение должно быть выполнено через анонимный класс. Тем не менее, я еще не понял, как мне его реализовать.

ответ

0
public interface Converter<I, O> { 

    void tranformer(List list); 

    O retriever(I obj); 
} 

_

public static <I, O> void transform(Converter<I, O> converter, List inputList) { 
     Iterator<I> it = inputList.iterator(); 
     List list = new LinkedList<>(); 
     while (it.hasNext()) { 
      list.add(converter.retriever(it.next())); 
     } 
     converter.tranformer(list); 
    } 

_

public static void main(String[] args) { 
     List<MyClass> list = new ArrayList<>(); 
     list.add(new myClass("John", 12); 
     list.add(new myClass("Mike", 16); 
     list.add(new myClass("Eric", 13); 
     list.add(new myClass("Mark", 142); 
     list.add(new myClass("Alex", 112); 

     MyClassCollection myclasscollection = new MyClassCollection(list); 
     final List collectionList = myclasscollection.collection(); 
     CollectionUtils.transform(new Converter<myClass, String>() { 
      @Override 
      public void tranformer(List list) { 
       employeeList.clear(); 
       employeeList.addAll(list); 
      } 

      @Override 
      public String retriever(myClass obj) { 
       return obj.name; // make the data member public or add getter 
      } 
     }, collectionList); 

collectionList.get(0).toString.toLowerCase(); 

} 

Это не в полной мере то, что вам нужно, но я держал пари, что это не плохая альтернатива. Пожалуйста, обратите внимание, что вывод коллекции CollectionList будет представлять собой коллекцию объектов (не String), однако вы можете получить доступ к методам типа данных String прямо вправо, как это collectionList.get(0).toString.toLowerCase(); Надейтесь на эту помощь.

3

Если вы используете Java 8, можно использовать stream с и map() сделать что-то вроде этого:

List<MyClass> myClassList = new ArrayList<>(); 
//add your items to myClassList here 

List<String> names = myClassList.stream().map(MyClass::getName).collect(Collectors.toList()); 
//names will now consist of a List of all the names associated with 
//each of the MyClass objects within myClassList in the same order 

Это решение использует метод ведения, а MyClass::getName. Это вызывает метод getName для каждого объекта в streammap, который отправляет его в соответствующее место в преобразованном потоке с использованием .map().

Далее используется .collect(), чтобы вернуть его с stream до list с использованием Collectors.toList().

Если вы работаете с большим количеством объектов в myClassList, этот процесс может быть ускорен с помощью .parallelStream() вместо .stream(), но если вы не работаете с большим количеством данных, вы можете увидеть снижение производительности с .parallelStream() , Все зависит от того, сколько объектов вы ожидаете присутствовать в пределах List.

Смежные вопросы