Arrays.stream(values)
.mapToObj(i -> Integer.toUnsignedString(i, 16))
.forEach(System.out::println);
Answer from JB Nizet on Stack OverflowVideos
You must assign the lambda expressions to variables of the functional interface types first.
Otherwise the compiler cannot infer the types of these lambda expressions.
I0 i0 = (int a, int b) -> a + b;
I1 i1 = (double d) -> (int) (d * 2);
List<Object> test = Arrays.asList(
i0,
i1
);
That said, I'm not sure what's the point of storing these lambda expressions in a List<Object>. You can't use them without casting them back to the individual functional interface types.
You could cast to the respective Interface like:
List<Object> test = Arrays.asList(
(I0) (int a, int b) -> a + b,
(I1) (double d) -> (int) (d * 2)
);
despite this being shorter, I would also consider Eran's answer maybe it is more readable and easier to understand (if having more functions). And I also can't see the use case for such a construct...
It gets even shorter (not necessarily better):
List<Object> test = Arrays.asList(
(I0) (a, b) -> a + b,
(I1) d -> (int) (d * 2)
);
Yes, you can do this by creating a DoubleStream from the array, filtering out the negatives, and converting the stream back to an array. Here is an example:
double[] d = {8, 7, -6, 5, -4};
d = Arrays.stream(d).filter(x -> x > 0).toArray();
//d => [8, 7, 5]
If you want to filter a reference array that is not an Object[] you will need to use the toArray method which takes an IntFunction to get an array of the original type as the result:
String[] a = { "s", "", "1", "", "" };
a = Arrays.stream(a).filter(s -> !s.isEmpty()).toArray(String[]::new);
even simpler, adding up to String[],
use built-in filter filter(StringUtils::isNotEmpty) of org.apache.commons.lang3
import org.apache.commons.lang3.StringUtils;
String test = "a\nb\n\nc\n";
String[] lines = test.split("\\n", -1);
String[] result = Arrays.stream(lines).filter(StringUtils::isNotEmpty).toArray(String[]::new);
System.out.println(Arrays.toString(lines));
System.out.println(Arrays.toString(result));
and output:
[a, b, , c, ]
[a, b, c]
Sure - I don't know how useful it is, but it's certainly doable:
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class Test
{
public static void main(String[] args)
{
Supplier<Test> supplier = () -> new Test();
List<Test> list = Stream
.generate(supplier)
.limit(10)
.collect(Collectors.toList());
System.out.println(list.size()); // 10
// Prints false, showing it really is calling the supplier
// once per iteration.
System.out.println(list.get(0) == list.get(1));
}
}
If you already have a pre-allocated array, you can use a lambda expression to populate it using Arrays.setAll or Arrays.parallelSetAll:
Arrays.setAll(persons, i -> new Person()); // i is the array index
To create a new array, you can use
Person[] persons = IntStream.range(0, 15) // 15 is the size
.mapToObj(i -> new Person())
.toArray(Person[]::new);
You can do it like this,
Optional<Preset> optional = Arrays.stream(presets)
.filter(x -> "MyString".equals(x.getName()))
.findFirst();
// Check whether optional has element you are looking for
if (optional.isPresent()) {
Preset p = optional.get(); // Get it from optional
}
You can read more about Optional here.
Like this:
Optional<Preset> preset = Arrays
.stream(presets)
.filter(x -> x.getName().equals("MyString"))
.findFirst();
This will return an Optional which might or might not contain a value. If you want to get rid of the Optional altogether:
Preset preset = Arrays
.stream(presets)
.filter(x -> x.getName().equals("MyString"))
.findFirst()
.orElse(null);
The filter() operation is an intermediate operation which returns a lazy stream, so there's no need to worry about the entire array being filtered even after a match is encountered.
I see no problem with using a loop for this. That's how I'd likely do it.
You can do it with a stream using reduce:
str = Arrays.stream(FORMAT)
.reduce(
str,
(s, country) -> s.replaceAll(country + "\\s", Matcher.quoteReplacement(simbol)));
Or, easier:
str = str.replaceAll(
Arrays.stream(FORMAT).collect(joining("|", "(", ")")) + "\\s",
Matcher.quoteReplacement(simbol));
Consider using a traditional for loop, since you're changing a global variable:
for(String country: FORMAT) {
str = str.replaceAll(country + "\\s", "\\" + simbol);
}
Using Streams in this example will make things less readable.
First note that you didn't specify what your ArrayList holds. I would assume it's Object. If it's however some container class then you need to adapt the code here and there a bit. Should be relatively easy. If you have difficulties, please don't bother commenting and giving additional information.
Without Java 8
Let's first take a look at how you would do it without Streams or Lambda:
ArrayList<Object> list = ...
List<String> result = new ArrayList<>();
// Iterate all elements
for (Object obj : list) {
// Ignore elements that are not of type String
if (!(obj instanceof String)) {
continue;
}
// The element is String, cast it
String objAsText = (String) obj;
// Collect it
result.add(objAsText);
}
The list result now only contains elements of the original list whose true type were String.
With Java 8 (Streams, Lambdas, Method references)
We can now easily write an equivalent version using the Stream API. Note that you probably confuse Streams in general with Lambda (they are different technologies, though Lambdas are often used in the Stream-API).
ArrayList<Object> list = ...
result = list.stream() // Stream<Object>
.filter(String.class::isInstance) // Stream<Object>
.map(String.class::cast) // Stream<String>
.collect(Collectors.toList());
That's it, quite easy and readable. The Collection#stream (documentation) returns a Stream consisting of the elements in the given collection. The Stream#filter (documentation) method returns a Stream where the elements not matching the condition are skipped. The Stream#map (documentation) transforms a Stream<X> into a Stream<Y> by applying the given method to all objects (X can be equal Y). Finally the Stream#collect (documentation) method collects all elements by using the given Collector.
If you however truly wanted to use Lambdas, then this might be more what you want:
ArrayList<Object> list = ...
List<String> result = new ArrayList<>();
list.forEach(obj -> { // This is a big lambda
// Ignore elements that are not of type String
if (!(obj instanceof String)) {
return;
}
// The element is String, cast it
String objAsText = (String) obj;
// Collect it
result.add(objAsText);
});
But I really think you confused the terms here.
If you want this as a lambda you can do the following:
Assuming you have a collection as follows:
Collection<Object> collection = new ArrayList<Object>();
collection.add(true);
collection.add("someStringValue");
Collection<String> onlyStrings = collection.stream()
.filter(String.class::isInstance)
.map(object -> (String) object)
.collect(Collectors.toList() );
//Now you have a collection of only Strings.