Skip to content

Commit

Permalink
yegor256#793 added FirstOf
Browse files Browse the repository at this point in the history
  • Loading branch information
krzyk committed May 8, 2018
1 parent 4738a00 commit c9b9b58
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
91 changes: 91 additions & 0 deletions src/main/java/org/cactoos/scalar/FirstOf.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2017-2018 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.scalar;

import java.util.NoSuchElementException;
import org.cactoos.Func;
import org.cactoos.Scalar;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.HeadOf;
import org.cactoos.iterable.IterableOf;

/**
* Find first element in a list that satisfies specified condition.
*
* <p>This class is thread-safe.
*
* @author Krzysztof Krason (Krzysztof.Krason@gmail.com)
* @version $Id$
* @param <T> Type of result
* @since 0.31
*/
public final class FirstOf<T> implements Scalar<T> {

/**
* Condition for getting the element.
*/
private final Func<T, Boolean> condition;

/**
* Source iterable.
*/
private final Iterable<T> source;

/**
* Fallback used if no value matches.
*/
private final Scalar<T> fallback;

/**
* Constructor.
* @param cond Condition for getting the element
* @param src Source iterable
* @param fbck Fallback used if no value matches
*/
public FirstOf(final Func<T, Boolean> cond, final Iterable<T> src,
final Scalar<T> fbck) {
this.condition = cond;
this.source = src;
this.fallback = fbck;
}

@Override
public T value() throws Exception {
return new ScalarWithFallback<>(
() -> new HeadOf<>(
1,
new Filtered<>(this.condition, this.source)
).iterator().next(),
new IterableOf<FallbackFrom<T>>(
new FallbackFrom<T>(
new IterableOf<Class<? extends Throwable>>(
NoSuchElementException.class
),
t1 -> this.fallback.value()
)
),
t -> t
).value();
}
}
86 changes: 86 additions & 0 deletions src/test/java/org/cactoos/scalar/FirstOfTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2017-2018 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.scalar;

import org.cactoos.iterable.IterableOf;
import org.cactoos.iterable.IterableOfInts;
import org.cactoos.matchers.ScalarHasValue;
import org.hamcrest.MatcherAssert;
import org.junit.Test;

/**
* Tests for {@link FirstOf}.
*
* <p>This class is thread-safe.
*
* @author Krzysztof Krason (Krzysztof.Krason@gmail.com)
* @version $Id$
* @since 0.31
* @checkstyle JavadocMethodCheck (500 lines)
*/
public final class FirstOfTest {

@Test
public void returnsMatchingValue() {
final int value = 1;
MatcherAssert.assertThat(
"Didn't return the only matching element",
new FirstOf<>(
i -> i >= value,
new IterableOfInts(0, value),
() -> -1
),
new ScalarHasValue<>(value)
);
}

@Test
public void returnsFirstValueForMultipleMatchingOnes() {
final String value = "1";
MatcherAssert.assertThat(
"Didn't return first matching element",
new FirstOf<>(
i -> !i.isEmpty(),
new IterableOf<>("1", "2"),
() -> ""
),
new ScalarHasValue<>(value)
);
}

@Test
public void returnsFallbackIfNothingMatches() {
final String value = "abc";
MatcherAssert.assertThat(
"Didn't return fallback",
new FirstOf<>(
i -> i.length() > 2,
new IterableOf<>("ab", "cd"),
() -> value
),
new ScalarHasValue<>(value)
);
}

}

0 comments on commit c9b9b58

Please sign in to comment.