Skip to content

Commit 4f93047

Browse files
committed
Adding ToArray for conveniently creating an A[] from Iterable<A>
1 parent 4e93dc7 commit 4f93047

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
1313
### Added
1414
- `Upcast` for safely casting up a type hierarchy
1515
- `SetLens`, lenses operating on `Set`s
16+
- `ToArray`, for converting `Iterable<A>` to `A[]`
1617

1718
## [3.0.0] - 2018-05-04
1819
### Changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn2;
2+
3+
import com.jnape.palatable.lambda.functions.Fn1;
4+
import com.jnape.palatable.lambda.functions.Fn2;
5+
6+
import java.lang.reflect.Array;
7+
import java.util.Collection;
8+
9+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Size.size;
10+
11+
/**
12+
* Write all the elements of an {@link Iterable} directly into an array of the specified type. If the {@link Iterable}
13+
* is an instance of {@link Collection}, use {@link Collection#toArray(Object[])}.
14+
*
15+
* @param <A> the {@link Iterable} element type
16+
*/
17+
public final class ToArray<A> implements Fn2<Class<A[]>, Iterable<? extends A>, A[]> {
18+
19+
private static final ToArray INSTANCE = new ToArray<>();
20+
21+
private ToArray() {
22+
}
23+
24+
@Override
25+
@SuppressWarnings("unchecked")
26+
public A[] apply(Class<A[]> arrayType, Iterable<? extends A> as) {
27+
A[] array = (A[]) Array.newInstance(arrayType.getComponentType(), size(as).intValue());
28+
if (as instanceof Collection)
29+
return ((Collection<A>) as).toArray(array);
30+
31+
int index = 0;
32+
for (A a : as) {
33+
array[index++] = a;
34+
}
35+
return array;
36+
}
37+
38+
@SuppressWarnings("unchecked")
39+
public static <A> ToArray<A> toArray() {
40+
return INSTANCE;
41+
}
42+
43+
public static <A> Fn1<Iterable<? extends A>, A[]> toArray(Class<A[]> arrayType) {
44+
return ToArray.<A>toArray().apply(arrayType);
45+
}
46+
47+
public static <A> A[] toArray(Class<A[]> arrayType, Iterable<? extends A> as) {
48+
return toArray(arrayType).apply(as);
49+
}
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jnape.palatable.lambda.functions.builtin.fn2;
2+
3+
import org.junit.Test;
4+
5+
import java.util.AbstractCollection;
6+
import java.util.Arrays;
7+
import java.util.Iterator;
8+
import java.util.List;
9+
10+
import static com.jnape.palatable.lambda.functions.builtin.fn2.ToArray.toArray;
11+
import static java.util.Arrays.asList;
12+
import static java.util.Collections.emptyIterator;
13+
import static org.junit.Assert.assertArrayEquals;
14+
15+
public class ToArrayTest {
16+
17+
@Test
18+
public void writesIterableToArray() {
19+
assertArrayEquals(new Integer[]{1, 2, 3}, toArray(Integer[].class, asList(1, 2, 3)));
20+
21+
List<? extends Integer> variance = asList(1, 2, 3);
22+
assertArrayEquals(new Object[]{1, 2, 3}, toArray(Object[].class, variance));
23+
}
24+
25+
@Test
26+
public void usesCollectionToArrayIfPossible() {
27+
Object sentinel = new Object();
28+
class CustomCollection extends AbstractCollection<Object> {
29+
@Override
30+
public Iterator<Object> iterator() {
31+
return emptyIterator();
32+
}
33+
34+
@Override
35+
public int size() {
36+
return 0;
37+
}
38+
39+
@Override
40+
@SuppressWarnings("unchecked")
41+
public <T> T[] toArray(T[] a) {
42+
T[] result = Arrays.copyOf(a, 1);
43+
result[0] = (T) sentinel;
44+
return result;
45+
}
46+
}
47+
48+
assertArrayEquals(new Object[]{sentinel}, toArray(Object[].class, new CustomCollection()));
49+
}
50+
}

0 commit comments

Comments
 (0)