This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new c83c322  ISIS-2666: Can<T>: add method pickByIndex(...)
c83c322 is described below

commit c83c322fa2035433f24287b39f47d15e98d5f2df
Author: [email protected] <[email protected]@luna>
AuthorDate: Fri May 14 14:58:39 2021 +0200

    ISIS-2666: Can<T>: add method pickByIndex(...)
---
 .../org/apache/isis/commons/collections/Can.java   | 16 ++++
 .../apache/isis/commons/collections/Can_Empty.java |  5 ++
 .../isis/commons/collections/Can_Multiple.java     | 17 +++++
 .../isis/commons/collections/Can_Singleton.java    | 25 ++++++
 .../apache/isis/commons/collections/CanTest.java   | 89 ++++++++++++++--------
 5 files changed, 120 insertions(+), 32 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can.java 
b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
index c37e75d..33741f5 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
@@ -539,6 +539,21 @@ extends Iterable<T>, Comparable<Can<T>>, Serializable {
 
     Can<T> remove(T element);
 
+    /**
+     * Given <i>n</i> indices, returns an equivalent of
+     * <pre>
+     * Can.of(
+     *     this.get(indices[0]).orElse(null),
+     *     this.get(indices[1]).orElse(null),
+     *     ...
+     *     this.get(indices[n-1]).orElse(null)
+     * )
+     * </pre>
+     * (where nulls are being ignored)
+     * @param indices - null-able
+     */
+    Can<T> pickByIndex(@Nullable int ...indices);
+
     // -- SEARCH
 
     /**
@@ -720,4 +735,5 @@ extends Iterable<T>, Comparable<Can<T>>, Serializable {
     T[] toArray(Class<T> elementType);
 
 
+
 }
diff --git 
a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java 
b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
index 331f356..997a8f5 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
@@ -169,6 +169,11 @@ final class Can_Empty<T> implements Can<T> {
     }
 
     @Override
+    public Can<T> pickByIndex(final @Nullable int... indices) {
+        return Can.empty();
+    }
+
+    @Override
     public int indexOf(T element) {
         return -1;
     }
diff --git 
a/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java 
b/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
index 965010d..1149952 100644
--- 
a/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
+++ 
b/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
@@ -220,6 +220,23 @@ final class Can_Multiple<T> implements Can<T> {
     }
 
     @Override
+    public Can<T> pickByIndex(final @Nullable int... indices) {
+        if(indices==null
+                ||indices.length==0) {
+            return Can.empty();
+        }
+        val newElements = new ArrayList<T>(indices.length);
+        final int maxIndex = size()-1;
+        for(int index:indices) {
+            if(index>=0
+                    && index<=maxIndex) {
+                newElements.add(elements.get(index));
+            }
+        }
+        return Can.ofCollection(newElements);
+    }
+
+    @Override
     public int indexOf(@NonNull T element) {
         return this.elements.indexOf(element);
     }
diff --git 
a/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java 
b/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
index cf930ee..65e09b6 100644
--- 
a/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
+++ 
b/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
@@ -194,6 +194,31 @@ final class Can_Singleton<T> implements Can<T> {
     }
 
     @Override
+    public Can<T> pickByIndex(final @Nullable int... indices) {
+        if(indices==null
+                ||indices.length==0) {
+            return Can.empty();
+        }
+        int pickCount = 0; // actual size of the returned Can<T>
+        for(int index:indices) {
+            if(index==0) {
+                ++pickCount;
+            }
+        }
+        if(pickCount==0) {
+            return Can.empty();
+        }
+        if(pickCount==1) {
+            return this;
+        }
+        val newElements = new ArrayList<T>(pickCount);
+        for(int i=0; i<pickCount; i++) {
+            newElements.add(element);
+        }
+        return Can.ofCollection(newElements);
+    }
+
+    @Override
     public int indexOf(@NonNull T element) {
         return this.element.equals(element) ? 0 : -1;
     }
diff --git 
a/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java 
b/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
index 6095a05..ed3311e 100644
--- a/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
+++ b/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
@@ -24,13 +24,13 @@ import java.util.stream.Stream;
 
 import org.junit.jupiter.api.Test;
 
+import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.commons.internal.testing._SerializationTester;
+
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.commons.internal.testing._SerializationTester;
-
 import lombok.val;
 
 class CanTest {
@@ -39,35 +39,35 @@ class CanTest {
     void tester_selftest() throws ClassNotFoundException, IOException {
         _SerializationTester.selftest();
     }
-    
+
     @Test
     void emptyCans_shouldBeEqual() {
         assertEquals(Can.empty(), Can.<String>of());
     }
-    
+
     @Test
     void emptyCan_shouldBeSerializable() {
         _SerializationTester.assertEqualsOnRoundtrip(Can.empty());
         _SerializationTester.assertEqualsOnRoundtrip(Can.<String>of());
     }
-    
+
     @Test
     void singletonCan_shouldBeSerializable() {
         _SerializationTester.assertEqualsOnRoundtrip(Can.<String>of("hi"));
     }
-    
+
     @Test
     void multiCan_shouldBeSerializable() {
         _SerializationTester.assertEqualsOnRoundtrip(Can.<String>of("hi", 
"there"));
     }
-    
+
     // -- REVERTING
-    
+
     @Test
     void multiCan_correctly_reverts() {
         assertEquals(Can.<String>of("c", "b", "a"), Can.<String>of("a", "b", 
"c").reverse());
     }
-    
+
     @Test
     void multiCan_startsWith() {
         assertTrue(Can.<String>of("a", "b", 
"c").startsWith(Can.<String>of("a", "b", "c")));
@@ -77,7 +77,7 @@ class CanTest {
         assertTrue(Can.<String>of("a", "b", "c").startsWith(null));
         assertFalse(Can.<String>of("a", "b", 
"c").startsWith(Can.<String>of("a", "b", "x")));
     }
-    
+
     @Test
     void multiCan_endsWith() {
         assertTrue(Can.<String>of("a", "b", "c").endsWith(Can.<String>of("a", 
"b", "c")));
@@ -87,88 +87,113 @@ class CanTest {
         assertTrue(Can.<String>of("a", "b", "c").endsWith(null));
         assertFalse(Can.<String>of("a", "b", "c").endsWith(Can.<String>of("x", 
"b", "a")));
     }
-    
+
     // -- FILTERING
-    
+
     @Test
     void emptyCanFilter_isIdentity() {
         assertEquals(Can.<String>empty(), 
Can.<String>empty().filter(x->false));
         assertEquals(Can.<String>empty(), Can.<String>empty().filter(null));
     }
-    
+
     @Test
     void singletonCanFilter_whenAccept_isIdentity() {
         assertEquals(Can.<String>of("hi"), 
Can.<String>of("hi").filter(x->true));
         assertEquals(Can.<String>of("hi"), Can.<String>of("hi").filter(null));
     }
-    
+
     @Test
     void canFilter_whenNotAccept_isEmpty() {
         assertEquals(Can.<String>empty(), 
Can.<String>of("hi").filter(x->false));
         assertEquals(Can.<String>empty(), Can.<String>of("hi", 
"there").filter(x->false));
     }
-    
+
     @Test
     void multiCanFilter_whenAccept_isIdentity() {
         assertEquals(Can.<String>of("hi", "there"), Can.<String>of("hi", 
"there").filter(x->true));
         assertEquals(Can.<String>of("hi", "there"), Can.<String>of("hi", 
"there").filter(null));
     }
-    
+
     @Test
     void multiCanFilter_whenAcceptOne_isDifferentCan() {
         assertEquals(Can.<String>of("there"), Can.<String>of("hi", 
"there").filter("there"::equals));
         assertEquals(Can.<String>of("hi"), Can.<String>of("hi", 
"there").filter("hi"::equals));
         assertEquals(Can.<String>of("hello"), Can.<String>of("hi", "hello", 
"there").filter("hello"::equals));
     }
-    
+
     @Test
     void multiCanFilter_whenAcceptTwo_isDifferentCan() {
         assertEquals(Can.<String>of("hi", "hello"), Can.<String>of("hi", 
"hello", "there").filter(x->x.startsWith("h")));
     }
-    
+
     // -- STREAM IDIOMS
-    
+
     @Test
     void partialSums_reversed() {
         assertEquals(Can.<String>of("a", "b"), 
Can.<String>empty().add("a").add("b"));
         assertEquals(Can.<String>of("a", "b"), Can.<String>empty().add(0, 
"b").add(0, "a"));
-        
+
         final Can<String> all = Can.<String>of("a", "b", "c");
-        
+
         val iterator = all.reverseIterator();
-        
+
         val partialSums = Stream.iterate(
-                Can.<String>empty(), 
+                Can.<String>empty(),
                 parts->parts.add(0, iterator.next()))
         .limit(4)
         .collect(Can.toCan());
-        
+
         assertEquals(Can.of(
                     Can.<String>empty(),
                     Can.<String>of("c"),
                     Can.<String>of("b", "c"),
                     Can.<String>of("a", "b", "c")
-                ), 
+                ),
                 partialSums);
-        
+
     }
-    
+
     // -- TO SET CONVERSION
-    
+
     @Test
     void multiCan_toSet_should_find_duplicates() {
         val expectedSet = _Sets.of("a", "b", "c");
         val duplicates = _Sets.<String>newHashSet();
-        
+
         assertSetEquals(expectedSet, Can.<String>of("a", "c", "b", 
"a").toSet());
         assertSetEquals(expectedSet, Can.<String>of("a", "c", "b", 
"a").toSet(duplicates::add));
         assertSetEquals(_Sets.of("a"), duplicates);
     }
-    
+
+    // -- PICKING
+
+    @Test
+    void can_pickByIndex() {
+
+        assertEquals(
+                Can.empty(),
+                Can.empty().pickByIndex(0, 1, 0));
+
+        assertEquals(
+                Can.empty(),
+                Can.<String>of("a", "b", "c").pickByIndex(-2, 5));
+
+        assertEquals(
+                Can.of("a", "a", "a"),
+                Can.<String>of("a").pickByIndex(0, 0, -2, 5, 0));
+
+        assertEquals(
+                Can.of("a", "b", "a"),
+                Can.<String>of("a", "b", "c").pickByIndex(0, 1, -2, 0, 5));
+    }
+
+    // -- HEPER
+
     private static <T> void assertSetEquals(Set<T> a, Set<T> b) {
         assertTrue(_Sets.minus(a, b).isEmpty());
         assertTrue(_Sets.minus(b, a).isEmpty());
     }
-    
+
+
 
 }

Reply via email to