user7411498
user7411498

Reputation:

transform Collection<myClass> to Collection<String>

I trying to implement functionally similar to CollectionUtils transform (Apache Commons Collections)

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 

My question is it possible to implement method transformerModifier in the way that it will change collection of the object myObj so that myObj.collection() return not the List<myClass> but the List of List<String> ( where string is the data from private String name data member of myClass ) ?

My guess is that the solution should be through anonymous class. However, I didn't understand yet how should I implement it.

Upvotes: 2

Views: 2170

Answers (2)

user7399825
user7399825

Reputation:

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

}

This isn't fully what you need but I bet this isn't bad alternative. Please, notice that could output collection collectionList will be collection of objects ( not String ), however, you can access to methods of the String data type just to right like this collectionList.get(0).toString.toLowerCase(); Hope this help.

Upvotes: -2

CraigR8806
CraigR8806

Reputation: 1584

If you are using Java 8, you could make use of streams and map() to do something like this:

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

This solution makes use of Method Reference as well MyClass::getName. This calls the getName method on each object in the stream mapping it to its respective spot in the transformed stream using .map().

Next it uses .collect() to bring it back from a stream to a list using Collectors.toList().

If you are working with a lot of objects within myClassList, this process can be sped up using .parallelStream() instead of .stream(), but if you are not working with a large amount of data, you may see a reduction in performance with .parallelStream(). It all depends on how many objects you expect to be present within the List.

Upvotes: 5

Related Questions