Easy way to convert Iterable to Collection

前端 未结 19 2171
忘了有多久
忘了有多久 2020-11-28 01:39

In my application I use 3rd party library (Spring Data for MongoDB to be exact).

Methods of this library return Iterable, while the rest of my

相关标签:
19条回答
  • 2020-11-28 02:31

    In Java 8 you can do this to add all elements from an Iterable to Collection and return it:

    public static <T> Collection<T> iterableToCollection(Iterable<T> iterable) {
      Collection<T> collection = new ArrayList<>();
      iterable.forEach(collection::add);
      return collection;
    }
    

    Inspired by @Afreys answer.

    0 讨论(0)
  • 2020-11-28 02:31

    Since RxJava is a hammer and this kinda looks like a nail, you can do

    Observable.from(iterable).toList().toBlocking().single();
    
    0 讨论(0)
  • 2020-11-28 02:32

    I didn't see a simple one line solution without any dependencies. I simple use

    List<Users> list;
    Iterable<IterableUsers> users = getUsers();
    
    // one line solution
    list = StreamSupport.stream(users.spliterator(), true).collect(Collectors.toList());
    
    0 讨论(0)
  • 2020-11-28 02:34

    With Guava you can use Lists.newArrayList(Iterable) or Sets.newHashSet(Iterable), among other similar methods. This will of course copy all the elements in to memory. If that isn't acceptable, I think your code that works with these ought to take Iterable rather than Collection. Guava also happens to provide convenient methods for doing things you can do on a Collection using an Iterable (such as Iterables.isEmpty(Iterable) or Iterables.contains(Iterable, Object)), but the performance implications are more obvious.

    0 讨论(0)
  • 2020-11-28 02:34

    I use my custom utility to cast an existing Collection if available.

    Main:

    public static <T> Collection<T> toCollection(Iterable<T> iterable) {
        if (iterable instanceof Collection) {
            return (Collection<T>) iterable;
        } else {
            return Lists.newArrayList(iterable);
        }
    }
    

    Ideally the above would use ImmutableList, but ImmutableCollection does not allow nulls which may provide undesirable results.

    Tests:

    @Test
    public void testToCollectionAlreadyCollection() {
        ArrayList<String> list = Lists.newArrayList(FIRST, MIDDLE, LAST);
        assertSame("no need to change, just cast", list, toCollection(list));
    }
    
    @Test
    public void testIterableToCollection() {
        final ArrayList<String> expected = Lists.newArrayList(FIRST, null, MIDDLE, LAST);
    
        Collection<String> collection = toCollection(new Iterable<String>() {
            @Override
            public Iterator<String> iterator() {
                return expected.iterator();
            }
        });
        assertNotSame("a new list must have been created", expected, collection);
        assertTrue(expected + " != " + collection, CollectionUtils.isEqualCollection(expected, collection));
    }
    

    I implement similar utilities for all subtypes of Collections (Set,List,etc). I'd think these would already be part of Guava, but I haven't found it.

    0 讨论(0)
  • 2020-11-28 02:36

    Concise solution with Java 8 using java.util.stream:

    public static <T> List<T> toList(final Iterable<T> iterable) {
        return StreamSupport.stream(iterable.spliterator(), false)
                            .collect(Collectors.toList());
    }
    
    0 讨论(0)
提交回复
热议问题