diff --git a/src/main/java/org/cactoos/func/ProcAsFunc.java b/src/main/java/org/cactoos/func/ProcAsFunc.java index 33d2caf3e0..ac41c7f061 100644 --- a/src/main/java/org/cactoos/func/ProcAsFunc.java +++ b/src/main/java/org/cactoos/func/ProcAsFunc.java @@ -46,17 +46,33 @@ public final class ProcAsFunc implements Func { */ private final Proc proc; + /** + * The result. + */ + private final Y result; + /** * Ctor. * @param prc The proc */ public ProcAsFunc(final Proc prc) { + this(prc, null); + } + + /** + * Ctor. + * @param prc The proc + * @param rslt Result to return + * @since 0.7 + */ + public ProcAsFunc(final Proc prc, final Y rslt) { this.proc = prc; + this.result = rslt; } @Override public Y apply(final X input) throws Exception { this.proc.exec(input); - return null; + return this.result; } } diff --git a/src/main/java/org/cactoos/list/FirstOf.java b/src/main/java/org/cactoos/list/ItemOfIterable.java similarity index 61% rename from src/main/java/org/cactoos/list/FirstOf.java rename to src/main/java/org/cactoos/list/ItemOfIterable.java index 6d90e464ed..3cc971be36 100644 --- a/src/main/java/org/cactoos/list/FirstOf.java +++ b/src/main/java/org/cactoos/list/ItemOfIterable.java @@ -24,22 +24,22 @@ package org.cactoos.list; import java.io.IOException; -import java.util.Iterator; import org.cactoos.Func; import org.cactoos.Scalar; import org.cactoos.text.FormattedText; /** - * First element in {@link Iterable} or fallback value if iterable is empty. + * Element from position in {@link Iterable} + * or fallback value if iterable hasn't this position. * *

There is no thread-safety guarantee. * * @author Kirill (g4s8.public@gmail.com) * @version $Id$ * @param Scalar type - * @since 0.1 + * @since 0.7 */ -public final class FirstOf implements Scalar { +public final class ItemOfIterable implements Scalar { /** * Source iterable. @@ -51,12 +51,17 @@ public final class FirstOf implements Scalar { */ private final Func, T> fbk; + /** + * Position. + */ + private final int pos; + /** * Ctor. * * @param src Iterable */ - public FirstOf(final Iterable src) { + public ItemOfIterable(final Iterable src) { this( src, itr -> { @@ -74,7 +79,7 @@ public FirstOf(final Iterable src) { * @param src Iterable * @param fbk Fallback value */ - public FirstOf(final Iterable src, final T fbk) { + public ItemOfIterable(final Iterable src, final T fbk) { this(src, itr -> fbk); } @@ -84,20 +89,58 @@ public FirstOf(final Iterable src, final T fbk) { * @param src Iterable * @param fbk Fallback value */ - public FirstOf(final Iterable src, final Func, T> fbk) { + public ItemOfIterable( + final Iterable src, + final Func, T> fbk + ) { + this(src, 0, fbk); + } + + /** + * Ctor. + * + * @param src Iterable + * @param pos Position + */ + public ItemOfIterable(final Iterable src, final int pos) { + this( + src, + pos, + itr -> { + throw new IOException( + new FormattedText( + "Iterable %s hasn't element from position %d", + itr, + pos + ).asString() + ); + } + ); + } + + /** + * Ctor. + * + * @param src Iterable + * @param pos Position + * @param fbk Fallback value + */ + public ItemOfIterable( + final Iterable src, + final int pos, + final Func, T> fbk + ) { + this.pos = pos; this.src = src; this.fbk = fbk; } @Override public T asValue() throws Exception { - final Iterator itr = this.src.iterator(); - final T ret; - if (itr.hasNext()) { - ret = itr.next(); - } else { - ret = this.fbk.apply(this.src); - } - return ret; + return new ItemOfIterator<>( + this.src.iterator(), + this.pos, + this.fbk + ).asValue(); } } diff --git a/src/main/java/org/cactoos/list/ItemOfIterator.java b/src/main/java/org/cactoos/list/ItemOfIterator.java new file mode 100644 index 0000000000..f5bae33408 --- /dev/null +++ b/src/main/java/org/cactoos/list/ItemOfIterator.java @@ -0,0 +1,161 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.cactoos.list; + +import java.io.IOException; +import java.util.Iterator; +import org.cactoos.Func; +import org.cactoos.Scalar; +import org.cactoos.text.FormattedText; + +/** + * Element from position in {@link Iterator} + * or fallback value if iterator hasn't this position. + * + *

There is no thread-safety guarantee. + * + * @author Ilia Rogozhin (ilia.rogozhin@gmail.com) + * @version $Id$ + * @param Scalar type + * @since 0.7 + */ +public final class ItemOfIterator implements Scalar { + + /** + * Source iterator. + */ + private final Iterator src; + + /** + * Fallback value. + */ + private final Func, T> fbk; + + /** + * Position. + */ + private final int pos; + + /** + * Ctor. + * + * @param src Iterator + */ + public ItemOfIterator(final Iterator src) { + this( + src, + itr -> { + throw new IOException( + new FormattedText("Iterator %s is empty", itr.iterator()) + .asString() + ); + } + ); + } + + /** + * Ctor. + * + * @param src Iterator + * @param fbk Fallback value + */ + public ItemOfIterator(final Iterator src, final T fbk) { + this(src, itr -> fbk); + } + + /** + * Ctor. + * + * @param src Iterator + * @param fbk Fallback value + */ + public ItemOfIterator( + final Iterator src, + final Func, T> fbk + ) { + this(src, 0, fbk); + } + + /** + * Ctor. + * + * @param src Iterator + * @param pos Position + */ + public ItemOfIterator(final Iterator src, final int pos) { + this( + src, + pos, + itr -> { + throw new IOException( + new FormattedText( + "Iterator %s hasn't element from position %d", + itr.iterator(), + pos + ).asString() + ); + } + ); + } + + /** + * Ctor. + * + * @param src Iterator + * @param pos Position + * @param fbk Fallback value + */ + public ItemOfIterator( + final Iterator src, + final int pos, + final Func, T> fbk + ) { + this.pos = pos; + this.src = src; + this.fbk = fbk; + } + + @Override + public T asValue() throws Exception { + if (this.pos < 0) { + throw new IOException( + new FormattedText( + "Position must be nonnegative! But position = %d", + this.pos + ).asString() + ); + } + final T ret; + int cur; + for (cur = 0; cur < this.pos && this.src.hasNext(); ++cur) { + this.src.next(); + } + if (cur == this.pos && this.src.hasNext()) { + ret = this.src.next(); + } else { + ret = this.fbk.apply(() -> this.src); + } + return ret; + } +} diff --git a/src/main/java/org/cactoos/list/SortedIterable.java b/src/main/java/org/cactoos/list/SortedIterable.java new file mode 100644 index 0000000000..29aaeccd76 --- /dev/null +++ b/src/main/java/org/cactoos/list/SortedIterable.java @@ -0,0 +1,96 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.cactoos.list; + +import java.util.Comparator; +import java.util.Iterator; + +/** + * Sorted iterable. + * + *

There is no thread-safety guarantee.

+ * + * @author Dusan Rychnovsky (dusan.rychnovsky@gmail.com) + * @version $Id$ + * @param Element type + * @since 0.7 + */ +public final class + SortedIterable> implements + Iterable { + + /** + * Decorated iterable. + */ + private final Iterable iterable; + + /** + * Comparator. + */ + private final Comparator comparator; + + /** + * Ctor. + * @param src The underlying iterable + */ + @SafeVarargs + @SuppressWarnings("varargs") + public SortedIterable(final T... src) { + this(new ArrayAsIterable<>(src)); + } + + /** + * Ctor. + * @param src The underlying iterable + */ + public SortedIterable(final Iterable src) { + this(Comparator.naturalOrder(), src); + } + + /** + * Ctor. + * @param src The underlying iterable + * @param cmp The comparator + */ + @SafeVarargs + @SuppressWarnings("varargs") + public SortedIterable(final Comparator cmp, final T... src) { + this(cmp, new ArrayAsIterable<>(src)); + } + + /** + * Ctor. + * @param src The underlying iterable + * @param cmp The comparator + */ + public SortedIterable(final Comparator cmp, final Iterable src) { + this.iterable = src; + this.comparator = cmp; + } + + @Override + public Iterator iterator() { + return new SortedIterator<>(this.comparator, this.iterable.iterator()); + } +} diff --git a/src/main/java/org/cactoos/list/SortedIterator.java b/src/main/java/org/cactoos/list/SortedIterator.java new file mode 100644 index 0000000000..2ae36a15e6 --- /dev/null +++ b/src/main/java/org/cactoos/list/SortedIterator.java @@ -0,0 +1,89 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.cactoos.list; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.cactoos.func.StickyScalar; +import org.cactoos.func.UncheckedScalar; + +/** + * Sorted iterator. + * + *

There is no thread-safety guarantee.

+ * + * @author Dusan Rychnovsky (dusan.rychnovsky@gmail.com) + * @version $Id$ + * @param Element type + * @since 0.7 + */ +public final class + SortedIterator> implements + Iterator { + + /** + * Sorted one. + */ + private final UncheckedScalar> sorted; + + /** + * Ctor. + * @param src The underlying iterator + */ + public SortedIterator(final Iterator src) { + this(Comparator.naturalOrder(), src); + } + + /** + * Ctor. + * @param src The underlying iterator + * @param cmp The comparator + */ + public SortedIterator(final Comparator cmp, final Iterator src) { + this.sorted = new UncheckedScalar<>( + new StickyScalar<>( + () -> { + final List items = new LinkedList<>(); + while (src.hasNext()) { + items.add(src.next()); + } + items.sort(cmp); + return items.iterator(); + } + ) + ); + } + + @Override + public boolean hasNext() { + return this.sorted.asValue().hasNext(); + } + + @Override + public T next() { + return this.sorted.asValue().next(); + } +} diff --git a/src/test/java/org/cactoos/io/StickyInputTest.java b/src/test/java/org/cactoos/io/StickyInputTest.java index 29db28038c..d0022b8ce2 100644 --- a/src/test/java/org/cactoos/io/StickyInputTest.java +++ b/src/test/java/org/cactoos/io/StickyInputTest.java @@ -23,6 +23,7 @@ */ package org.cactoos.io; +import org.cactoos.Input; import org.cactoos.TextHasString; import org.cactoos.func.FuncAsMatcher; import org.cactoos.func.RepeatedFunc; @@ -51,7 +52,7 @@ public void readsFileContent() { ) ), new FuncAsMatcher<>( - new RepeatedFunc<>( + new RepeatedFunc( input -> new InputAsBytes( new TeeInput(input, new DeadOutput()) // @checkstyle MagicNumber (2 lines) diff --git a/src/test/java/org/cactoos/list/FirstOfTest.java b/src/test/java/org/cactoos/list/ItemOfIterableTest.java similarity index 73% rename from src/test/java/org/cactoos/list/FirstOfTest.java rename to src/test/java/org/cactoos/list/ItemOfIterableTest.java index 3adf6f3c4f..d2222a61dd 100644 --- a/src/test/java/org/cactoos/list/FirstOfTest.java +++ b/src/test/java/org/cactoos/list/ItemOfIterableTest.java @@ -24,48 +24,61 @@ package org.cactoos.list; import java.io.IOException; -import java.util.Arrays; import java.util.Collections; import org.cactoos.ScalarHasValue; import org.hamcrest.MatcherAssert; import org.junit.Test; /** - * Test case for {@link FirstOf}. + * Test case for {@link ItemOfIterable}. * * @author Kirill (g4s8.public@gmail.com) * @version $Id$ - * @since 0.1 + * @since 0.7 * @checkstyle JavadocMethodCheck (500 lines) */ -public final class FirstOfTest { +public final class ItemOfIterableTest { @Test public void firstElementTest() throws Exception { MatcherAssert.assertThat( "Can't take the first item from the iterable", - new FirstOf<>( + new ItemOfIterable<>( // @checkstyle MagicNumber (1 line) - Arrays.asList(1, 2, 3) + new ArrayAsIterable<>(1, 2, 3) ), new ScalarHasValue<>(1) ); } + @Test + public void elementByPosTest() throws Exception { + MatcherAssert.assertThat( + "Can't take the item by position from the iterable", + new ItemOfIterable<>( + // @checkstyle MagicNumber (1 line) + new ArrayAsIterable<>(1, 2, 3), + 1 + ), + new ScalarHasValue<>(2) + ); + } + @Test(expected = IOException.class) public void failForEmptyCollectionTest() throws Exception { - new FirstOf<>(Collections.emptyList()).asValue(); + new ItemOfIterable<>(Collections.emptyList()).asValue(); } @Test public void fallbackTest() throws Exception { + final String fallback = "fallback"; MatcherAssert.assertThat( "Can't fallback to default value", - new FirstOf<>( + new ItemOfIterable<>( Collections.emptyList(), - 1 + fallback ), - new ScalarHasValue<>(1) + new ScalarHasValue<>(fallback) ); } } diff --git a/src/test/java/org/cactoos/list/ItemOfIteratorTest.java b/src/test/java/org/cactoos/list/ItemOfIteratorTest.java new file mode 100644 index 0000000000..d103b16dd7 --- /dev/null +++ b/src/test/java/org/cactoos/list/ItemOfIteratorTest.java @@ -0,0 +1,101 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.cactoos.list; + +import java.io.IOException; +import java.util.Collections; +import org.cactoos.ScalarHasValue; +import org.hamcrest.MatcherAssert; +import org.junit.Test; + +/** + * Test Case for {@link ItemOfIterator}. + * @author Ilia Rogozhin (ilia.rogozhin@gmail.com) + * @version $Id$ + * @since 0.7 + * @checkstyle JavadocMethodCheck (500 lines) + */ +public final class ItemOfIteratorTest { + + @Test + public void firstElementTest() throws Exception { + MatcherAssert.assertThat( + "Can't take the first item from the iterator", + new ItemOfIterator<>( + // @checkstyle MagicNumber (1 line) + new ArrayAsIterable<>(1, 2, 3).iterator() + ), + new ScalarHasValue<>(1) + ); + } + + @Test + public void elementByPosTest() throws Exception { + MatcherAssert.assertThat( + "Can't take the item by position from the iterator", + new ItemOfIterator<>( + // @checkstyle MagicNumber (1 line) + new ArrayAsIterable<>(1, 2, 3).iterator(), + 1 + ), + new ScalarHasValue<>(2) + ); + } + + @Test(expected = IOException.class) + public void failForEmptyCollectionTest() throws Exception { + new ItemOfIterator<>(Collections.emptyIterator()).asValue(); + } + + @Test(expected = IOException.class) + public void failForNegativePositionTest() throws Exception { + new ItemOfIterator<>( + // @checkstyle MagicNumber (1 line) + new ArrayAsIterable<>(1, 2, 3).iterator(), + -1 + ).asValue(); + } + + @Test + public void fallbackTest() throws Exception { + final String fallback = "fallback"; + MatcherAssert.assertThat( + "Can't fallback to default value", + new ItemOfIterator<>( + Collections.emptyIterator(), + fallback + ), + new ScalarHasValue<>(fallback) + ); + } + + @Test(expected = IOException.class) + public void failForPosMoreLengthTest() throws Exception { + new ItemOfIterator<>( + // @checkstyle MagicNumberCheck (2 lines) + new ArrayAsIterable<>(1, 2, 3).iterator(), + 3 + ).asValue(); + } +} diff --git a/src/test/java/org/cactoos/list/IterableAsMapTest.java b/src/test/java/org/cactoos/list/IterableAsMapTest.java index 57bb9a4c49..5c8ee2b1c0 100644 --- a/src/test/java/org/cactoos/list/IterableAsMapTest.java +++ b/src/test/java/org/cactoos/list/IterableAsMapTest.java @@ -39,11 +39,10 @@ public final class IterableAsMapTest { @Test - @SuppressWarnings("unchecked") public void convertsIterableToMap() { MatcherAssert.assertThat( "Can't convert iterable to map", - new IterableAsMap<>( + new IterableAsMap( new AbstractMap.SimpleEntry<>(0, "hello, "), new AbstractMap.SimpleEntry<>(1, "world!") ), diff --git a/src/test/java/org/cactoos/list/SortedIterableTest.java b/src/test/java/org/cactoos/list/SortedIterableTest.java new file mode 100644 index 0000000000..afce12b66f --- /dev/null +++ b/src/test/java/org/cactoos/list/SortedIterableTest.java @@ -0,0 +1,82 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.cactoos.list; + +import java.util.Collections; +import java.util.Comparator; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.Test; + +/** + * Test case for {@link SortedIterable}. + * + * @author Yegor Bugayenko (yegor256@gmail.com) + * @version $Id$ + * @since 0.7 + * @checkstyle JavadocMethodCheck (500 lines) + * @checkstyle MagicNumberCheck (500 lines) + */ +public final class SortedIterableTest { + + @Test + public void sortsAnArray() throws Exception { + MatcherAssert.assertThat( + "Can't sort an iterable", + new SortedIterable<>( + new ArrayAsIterable<>( + 3, 2, 10, 44, -6, 0 + ) + ), + Matchers.hasItems(-6, 0, 2, 3, 10, 44) + ); + } + + @Test + @SuppressWarnings("PMD.AvoidDuplicateLiterals") + public void sortsAnArrayWithComparator() throws Exception { + MatcherAssert.assertThat( + "Can't sort an iterable with a comparator", + new SortedIterable<>( + Comparator.reverseOrder(), + new ArrayAsIterable<>( + "a", "c", "hello", "dude", "Friend" + ) + ), + Matchers.hasItems("hello", "dude", "c", "a", "Friend") + ); + } + + @Test + public void sortsAnEmptyArray() throws Exception { + MatcherAssert.assertThat( + "Can't sort an empty iterable", + new SortedIterable( + Collections.emptyList() + ), + Matchers.iterableWithSize(0) + ); + } + +}