Java: Converting lists of one element type to a list of another type

前端 未结 9 605
借酒劲吻你
借酒劲吻你 2021-02-01 21:18

I\'m writing an adapter framework where I need to convert a list of objects from one class to another. I can iterate through the source list to do this as in

Java: Best

相关标签:
9条回答
  • 2021-02-01 21:42

    Java 8 way:

    List<String> original = ...;
    List<Wrapper> converted = original.stream().map(Wrapper::new).collect(Collectors.toList());
    

    assuming Wrapper class has a constructor accepting a String.

    0 讨论(0)
  • 2021-02-01 21:48

    I think you would either have to create a custom List (implementing the List interface) or a custom Iterator. For example:

    ArrayList<String> targetList = new ArrayList<String>();
    ConvertingIterator<String> iterator = new ConvertingIterator<String>(targetList);
    // and here you would have to use a custom List implementation as a source List
    // using the Iterator created above
    

    But I doubt that this approach would save you much.

    0 讨论(0)
  • 2021-02-01 21:52

    My answer to that question applies to your case:

    import com.google.common.collect.Lists;
    import com.google.common.base.Functions
    
    List<Integer> integers = Arrays.asList(1, 2, 3, 4);
    
    List<String> strings = Lists.transform(integers, Functions.toStringFunction());
    

    The transformed list is a view on the original collection, so the transformation happens when the destination List is accessed.

    0 讨论(0)
  • 2021-02-01 21:52

    You can write a mapping iterator that decorates an existing iterator and applies a function on it. In this case, the function transforms the objects from one type to another "on-the-fly".

    Something like this:

    import java.util.*;
    
    abstract class Transformer<T, U> implements Iterable<U>, Iterator<U> {
        public abstract U apply(T object);  
    
        final Iterator<T> source;       
        Transformer(Iterable<T> source)    { this.source = source.iterator(); }
    
        @Override public boolean hasNext() { return source.hasNext(); }
        @Override public U next()          { return apply(source.next()); }
        @Override public void remove()     { source.remove(); } 
    
        public Iterator<U> iterator()      { return this; }
    }
    
    public class TransformingIterator { 
        public static void main(String args[]) {
            List<String> list = Arrays.asList("1", "2", "3");
            Iterable<Integer> it = new Transformer<String, Integer>(list) {
                @Override public Integer apply(String s) {
                    return Integer.parseInt(s);
                }
            };
            for (int i : it) {
                System.out.println(i);
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-01 21:52

    Lambdaj allows to do that in a very simple and readable way. For example, supposing you have a list of Integer and you want to convert them in the corresponding String representation you could write something like that;

    List<Integer> ints = asList(1, 2, 3, 4);
    Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
        public String convert(Integer i) { return Integer.toString(i); }
    });
    

    Lambdaj applies the conversion function only while you're iterating on the result. There is also a more concise way to use the same feature. The next example works supposing that you have a list of persons with a name property and you want to convert that list in an iterator of person's names.

    Iterator<String> namesIterator = convertIterator(persons, on(Person.class).getName());
    

    Pretty easy. Isn't it?

    0 讨论(0)
  • 2021-02-01 21:53

    Well, you could create your own iterator wrapper class to do this. But I doubt that you would save much by doing this.

    Here's a simple example that wraps any iterator to a String iterator, using Object.toString() to do the mapping.

    public MyIterator implements Iterator<String> {
    
        private Iterator<? extends Object> it;
    
        public MyIterator(Iterator<? extends Object> it) {
            this.it = it;
        }
    
        public boolean hasNext() {
            return it.hasNext();
        }
    
        public String next() {
            return it.next().toString();
        }
    
        public void remove() {
            it.remove();
        }
    }
    
    0 讨论(0)
提交回复
热议问题