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.
Answer from Zabuzard on Stack OverflowVideos
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.
You can certainly create such a list as:
List<BinaryOperator<Integer>> opcodes = Arrays.asList((x, y) -> y, (x, y) -> ++x);
// sample
int a=14,b=16;
System.out.println(opcodes.get(0).apply(a, b)); // prints 16
System.out.println(opcodes.get(1).apply(a, b)); // prints 15
Or redressing the way you were trying to initializing the list
List<BinaryOperator<Integer>> opcodes = new ArrayList<BinaryOperator<Integer>>() {{
add((x, y) -> y);
add((x, y) -> ++x);
add((x, y) -> --x);
add((x, y) -> x + y);
add((x, y) -> x - y);
}};
In additional @nullpointer's great answer, you can also consider using a Map key to retain the original OPCODE intention of the functions, which would be lst in the array, e.g. using an Enum as a key:
public enum OPCODES {
MOV, ADD, XOR
}
Which can be bootstrapped:
Map<OPCODES, BinaryOperator<Integer>> opcodeMap =
new EnumMap<OPCODES, BinaryOperator<Integer>>(OPCODES.class);
opcodeMap.put(OPCODES.ADD, (x, y)-> x + y);
opcodeMap.put(OPCODES.MOV, (x, y) -> y);
opcodeMap.put(OPCODES.XOR, (x, y) -> x ^ y);
And used:
System.out.println(opcodeMap.get(OPCODES.ADD).apply(1, 2));
System.out.println(opcodeMap.get(OPCODES.MOV).apply(1, 2));
System.out.println(opcodeMap.get(OPCODES.XOR).apply(1, 2));