is there a Java equivalent to Javascript's "some" method? - java

I have a collection and I would like to know if at least one element meets some condition. Essentially, what some does in JavaScript, I would like to do on a collection!

As of Java 8, you can convert the Collection into a Stream and use anyMatch as in the following example.
import java.util.Arrays;
import java.util.List;
public class SomeExample {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, -6, 7);
boolean hasNegative = list.stream().anyMatch(x -> x < 0);
if (hasNegative) {
System.out.println("List contains some negative number");
}
else {
System.out.println("List does not contain any negative number");
}
}
}

Check out Guava's Iterables class and its any() implementation.
More or less the same thing as the Commons Collections example in the other answer, but genericized:
List<String> strings = Arrays.asList("ohai", "wat", "fuuuu", "kthxbai");
boolean well = Iterables.any(strings, new Predicate<String>() {
#Override public boolean apply(#Nullable String s) {
return s.equalsIgnoreCase("fuuuu");
}
});
System.out.printf("Do any match? %s%n", well ? "Yep" : "Nope");

You can use CollectionUtils from Apache commons-collections:
List<Integer> primes = Arrays.asList(3, 5, 7, 11, 13)
CollectionUtils.exists(primes, even); //false
Where even is a predicate:
Predicate even = new Predicate() {
public boolean evaluate(Object object) {
return ((Integer)object) % 2 == 0;
}
}
Or in an inlined version:
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13)
CollectionUtils.exists(primes, new Predicate() {
public boolean evaluate(Object object) {
return ((Integer)object) % 2 == 0;
}
});
Yes, it is ugly for two reasons:
Java does not (yet) support functions as first-class citizens, which are emulated with Single-Abstract-Method interface.
commons-collections does not support generics.
On the other hand in modern JVM languages like Scala you can write:
List(3,5,7,11,13,17).exists(_ % 2 == 0)

Java doesn't have this feature built-in. Javascript's some() accepts a function pointer as an argument, which is not something that's natively supported in Java. But it should be fairly straight forward to emulate the functionality of some() in Java using a loop and and an interface for the callback functionality.

Related

How to sort sequential decimal values in java

Basically, I have a set of BigDecimal values for example
[3.2,3.10,3.12,3.17,3.9].
I want to sort them based on the values after the dot using java.
The expected output should be like [3.2,3.9,3.10,3.12,3.17].
how do I write a code for this can you please help?
It seems you actually want to process version numbers, so I strongly discourage from abusing BigDecimal for that purpose. It’s too easy to accidentally confuse your logic with BigDecimal’s original numeric semantics.
Create your own class reflecting the actual purpose, e.g.
public record Version(int major, int minor) implements Comparable<Version> {
public static Version parse(String s) {
int dot = s.indexOf('.');
return dot < 0? new Version(Integer.parseInt(s), 0):
new Version(Integer.parseInt(s, 0, dot, 10),
Integer.parseInt(s, dot + 1, s.length(), 10));
}
#Override
public int compareTo(Version v) {
return major != v.major?
Integer.compare(major, v.major): Integer.compare(minor, v.minor);
}
#Override
public String toString() {
return major + "." + minor;
}
}
With such a class, you’ll never run into the problem of contradicting semantics.
When you use it with ,e.g.
Stream.of("3.2","3.10","3.12","3.17","3.9").map(Version::parse)
.sorted().forEachOrdered(System.out::println);
It will print
3.2
3.9
3.10
3.12
3.17
Create a method that returns the decimal part according to the scale of the given number
(e.g. calling it with 3.10 will return 10):
private static BigDecimal decimalPart(BigDecimal num) {
var dec = num.remainder(BigDecimal.ONE); // decimal part (e.g. 0.10)
var adj = dec.movePointRight(dec.scale());
return adj;
}
then use that to create a Comparator used for sorting:
var byDecimalPart = Comparator.comparing(SortedDecimal::decimalPart);
var sorted = input
.stream()
.sorted(byDecimalPart)
.toList(); // or .collect(...) or .forEach(...)
probably not correct for negative numbers (missing specification)

How to find the inverse of a matrix using Apache Commons Math library in Java?

I'm trying to find the inverse of a matrix using the Apache Commons Math Library.
Below is my attempt at doing just that:
BigReal[][] leftMatrixData = new BigReal[][] {
{ new BigReal(1), new BigReal(0), new BigReal(0), new BigReal(0) },
{ new BigReal(1), new BigReal(0), new BigReal(1), new BigReal(0) },
{ new BigReal(1), new BigReal(1), new BigReal(0), new BigReal(0) },
{ new BigReal(1), new BigReal(1), new BigReal(1), new BigReal(1) },
};
FieldMatrix<BigReal> leftMatrix = MatrixUtils.createFieldMatrix(leftMatrixData);
FieldMatrix<BigReal> leftMatrixInverse = new FieldLUDecomposition<>(leftMatrix)
.getSolver()
.getInverse();
When I run this, I get the following error:
org.apache.commons.math3.exception.MathArithmeticException: zero not allowed here
at org.apache.commons.math3.util.BigReal.divide(BigReal.java:255)
at org.apache.commons.math3.util.BigReal.divide(BigReal.java:39)
at org.apache.commons.math3.linear.FieldLUDecomposition.<init>(FieldLUDecomposition.java:160)
When I go to line 160 of FieldLUDecomposition.java per the above error message, I see that the library thinks this matrix is Singular i.e. it thinks it has no inverse:
public T getDeterminant() {
if (this.singular) { <---- this is line 160
return (FieldElement)this.field.getZero();
} else {
int m = this.pivot.length;
T determinant = this.even ? (FieldElement)this.field.getOne() : (FieldElement)((FieldElement)this.field.getZero()).subtract(this.field.getOne());
However, doing a quick check on WolframAlpha shows that this matrix has a non-zero determinant and indeed has an inverse:
So the question is - what am I doing wrong and how do I find the inverse of my matrix? Am I using the wrong solver?
Below is based on apache common math 3.6.1
A ticket is raised concerning this issue, I submitted a patch to fix the problem and the fix version will be 4.0 (not yet released as of 2021-07-19)
The reason of issue is equals method in BigReal
#Override
public boolean equals(Object other) {
if (this == other){
return true;
}
if (other instanceof BigReal){
return d.equals(((BigReal) other).d);
}
return false;
}
where d is BigDecimal, the backing value of BigReal. This cause equals comparison return undesired result when two BigReal has d with same value but different scale, and cause error when initializing FieldLUDecomposition. For BigDecimal we should check
return d.compareTo((BigReal) other) == 0;
instead.
Solution:
Check if workaround section(Copy BigReal as local class and change equals) helps.
Wait for version 4.0 release.
If double value matrix is acceptable,
Use RealMatrix instead, and MatrixUtils provide handy inverse method
import org.apache.commons.math3.linear.MatrixUtils;
import org.apache.commons.math3.linear.RealMatrix;
public class CalculateInverse {
public static void main(String[] args) {
double[][] matrixData = new double[][]{
{1, 0, 0, 0},
{1, 0, 1, 0},
{1, 1, 0, 0},
{1, 1, 1, 1}
};
RealMatrix matrix = MatrixUtils.createRealMatrix(matrixData);
RealMatrix inverse = MatrixUtils.inverse(matrix);
System.out.println(inverse);
}
}

Passing int array in ParameterizedTest in java

I am trying to pass in an array for testing a certain algorithm, but the arrays seem to not be passed correctly or at all. I manually tested the algorithm so I know it works as it's supposed to. How can I pass arrays in for testing in JUnit 5?
#ParameterizedTest
#CsvSource(value = {"[13,14,65,456,31,83],[1331,65456]"})
public void palindromeCombos(int[] input, int[] expected){
Palindrome pal = new Palindrome();
List<Integer> actual = pal.allPalindromes(input);
int[] result = new int[actual.size()];
for(int i = 0; i < actual.size(); i++){
result[i] = actual.get(i);
}
Assertions.assertArrayEquals(expected, result);
}
Pablo's Answer is correct, of course, but personally I'm not a fan of parsing strings if I don't absolutely have to. Another approach could be to use a MethodSource instead, and explicitly provide the arguments you need:
public static Stream<Arguments> palindromeCombos() {
return Stream.of(
Arguments.of(new int[]{13, 14, 65, 456, 31, 83}, new int[]{1331, 65456}));
}
#ParameterizedTest
#MethodSource
public void palindromeCombos(int[] input, int[] expected) {
// Test logic...
}
Since there is not implicit conversion for arrays, you can use explicit conversion, first you need to declare you converter class:
class IntArrayConverter implements ArgumentConverter {
#Override
public Object convert(Object source, ParameterContext context)
throws ArgumentConversionException {
if (!(source instanceof String)) {
throw new IllegalArgumentException(
"The argument should be a string: " + source);
}
try {
return Arrays.stream(((String) source).split(",")).mapToInt(Integer::parseInt).toArray();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("Failed to convert", e);
}
}
}
Then you can use it in your test:
#ParameterizedTest
#CsvSource(value = {
"13,14,65,456,31,83;1331,65456",
"1,2,3,4,5,6;10,20"}, delimiterString = ";")
public void palindromeCombos(#ConvertWith(IntArrayConverter.class) int[] input,
#ConvertWith(IntArrayConverter.class) int[] expected) {
System.out.println(Arrays.toString(input));
System.out.println(Arrays.toString(expected));
}
Notice that I removed the [] from the CsvSource and changed the delimiter to ;, so the arrays are expressed by a list of integers separated by comma.
If you want you can keep the format you had and handle it in the converter class.
For those two examples the output is:
[13, 14, 65, 456, 31, 83]
[1331, 65456]
[1, 2, 3, 4, 5, 6]
[10, 20]
If you need further information you can check this post: https://www.baeldung.com/parameterized-tests-junit-5

Enumerating a n-item combination of set Java/Groovy

I'm trying to write an operation that can enumerate all the combinations of a set of N elements. In other words, the N is unknown and depends on user input. On receiving the N, the function should be able to give all the possible combination of an N-item set, with all elements from a set U. Say, U={A,B,C...J}, 10 elements in total.
One more example of what I need, the function enumerate(3) should tell me all the possible combinations like {A,B,C},{A,D,J} etc., using elements picked from U.
I tried to do this in a way using for loops(initializing an integer since the size of U happen to be 10 in this case, so I can use 123 to denote {A,B,C}...). But the code smells bad and I'd like to know how this can be done in a more elegant with using recursive calls.
Java/Groovy are both acceptable (because I'm trying in them too). If anybody could provide ideas how to do this with closures in Groovy it'll be even more appreciated.
Also please don't use integers to denote the combination as I did, because I think this only applies to a certain U with no generality.
Thanks!
I believe I have the solution.
import java.util.HashSet;
import java.util.Set;
public class Generator<T> {
Set<T> source;
Set<Set<T>> combinations;
public Generator(Set<T> source) {
this.source = source;
}
public static void main(String[] args) {
final Set<String> source = new HashSet<>();
for (char character = 'A'; character <= 'Z'; character++){
source.add(String.valueOf(character));
}
final Generator<String> stringGenerator = new Generator<>(source);
stringGenerator.generate(3);
}
public void generate(int size){
if (size == 0){
return;
}
Set<Set<T>> newCombinations = new HashSet<>();
for (T element : source) {
if (combinations == null || combinations.isEmpty()){
final HashSet<T> set = new HashSet<>();
set.add(element);
newCombinations.add(set);
} else {
for (Set<T> combination : combinations) {
final HashSet<T> newCombination = new HashSet<>(combination);
if (newCombination.add(element)) {
newCombinations.add(newCombination);
}
}
}
}
combinations = newCombinations;
generate(size - 1);
}
}
It was fast dirty implementation, so probably it misses some cases, but it generally demonstrates the idea with at least one working case.

Modularly stubbing consecutive method calls with Mockito

I am trying to use Mockito to mock a "Reader" type class. Think of a data stream reader, it has methods to read various data types and advance the internal pointer after each read.
public interface Reader {
int readInt();
short readShort();
}
The class being tested reads in various data structures from the data stream. For example,
public class Somethings {
public List<Something> somethings;
public Somethings(Reader reader) {
somethings = new List<Something>();
int count = reader.readInt();
for (int i=0; i<count; i++) {
somethings.add(readSomething(reader));
}
}
private Something readSomething(Reader reader) {
int a = reader.readInt();
short b = reader.readShort();
int c = reader.readInt();
return new Something(a, b, c);
}
}
And finally, I have my test:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
readCount(reader, 2);
readSomething(reader, 1, 2, 3);
readSomething(reader, 4, 5, 6);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
private void readCount(Reader reader, int count) {
when(reader.readInt()).thenReturn(count);
}
private void readSomething(Reader reader, int a, short b, int c) {
when(reader.readInt()).thenReturn(a);
when(reader.readShort()).thenReturn(b);
when(reader.readInt()).thenReturn(c);
}
}
Unfortunately, this does not work. reader.readInt() always returns 6 for every invocation. And I understand why it returns 6. That is not my question.
There are two options I can think of to fix the tests, but I don't particularly like either one.
The first option would be something like:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
when(reader.readInt())
.thenReturn(2)
.thenReturn(1)
.thenReturn(3)
.thenReturn(4)
.thenReturn(6);
when(reader.readShort())
.thenReturn(2)
.thenReturn(5);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
}
This should work, but it's very monolithic and messy. It's difficult to see which return is for which piece of which structure, because they're all intermixed, with no structure.
The second option I can think of is something like:
public class SomethingsTest {
#Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);
NewOngoingStubbing readIntStub = when(reader.readInt());
NewOngoingStubbing readShortStub = when(reader.readShort());
readCount(readIntStub, 2);
readSomething(readIntStub, readShortStub, 1, 2, 3);
readSomething(readIntStub, readShortStub, 4, 5, 6);
Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
private void readCount(NewOngoingStubbing readIntStub, int count) {
readIntStub.thenReturn(count);
}
private void readSomething(NewOngoingStubbing readIntStub,
NewOngoingStubbing readShortStub, int a, short b, int c) {
readIntStub.thenReturn(a);
readShortStub.thenReturn(b);
readIntStub.thenReturn(c);
}
}
This at least maintains the structure of the original, but having to pass a separate object for each method call you want to make on the stubbed object is... ugh.
What would be the cleanest way to perform this test? Is there some option I'm missing here? Some functionality that I can leverage? I just started using Mockito tonight.. so I could very well be missing something.
Mockito does ongoing stubbing natively. Your first example is fine, but this should also work:
when(reader.readInt()).thenReturn(2, 1, 3, 4, 6);
The documentation for it is here.
If you have something handling particularly complex interaction, it's OK to roll out your own stub class. You may find that initialising some fake with realistic data, then using that, provides a clearer example of how the classes collaborate than Mockito can. If that's the case, go with clarity over convention. Mockito is IMO the best mocking framework out there, but sometimes I still roll my own.
When the standard methods for Mockito don't provide a mechanism to simulate your behavior, you can resort to implementing your own Answer. This is more work but provides extra flexibility.
Depending on your precise requirements, you could for instance create an Answer that returns a new element from a list of numbers, regardless of the request type (int or short). The variable readList can be a member that you can access from all the functions you use to set up your results.
final List<Integer> readList = new ArrayList<>();
// ... Fill readList with answers
Answer answerFromList = new Answer() {
Object answer(InvocationOnMock invocation) {
// Remove and return first element
return readList.remove(0);
}
}
when(reader.readInt()).thenAnswer(answerFromList);
when(reader.readShort()).thenAnswer(answerFromList);
Note that this Answer is a lot like the provided ReturnElementsOf, so you could use that directly as well.
You may create a class to deal with it, e.g.
private static class ReaderStubber {
private final Reader reader = Mockito.mock(Reader.class);
private final NewOngoingStubbing readIntStub = when(reader.readInt());;
private final NewOngoingStubbing readShortStub = when(reader.readShort());;
public Reader getReader() {
return reader;
}
private void readCount(int count) {
readIntStub.thenReturn(count);
}
private void readSomething(int a, short b, int c) {
readIntStub.thenReturn(a);
readShortStub.thenReturn(b);
readIntStub.thenReturn(c);
}
}
But then the question is, do you really need to do this with Mockito? Not everything should be mocked. Maybe just implementing a stub Reader for the test with some List<Integer> inside is better.
(Edit)
Also, if this is possible, maybe you should redesign the Reader to make it immutable and return some NewOngoingReading. Frequently (but not always) things that are hard to test are better to redesign. Also, you will not need to deal with synchronization.

Categories