Convert Java 8 feature to Java 1.5 - java-8

How do I convert the below mentioned piece of code in Java 1.5?
final List<String> filteredEntries = entries.stream()
.filter(e -> e.toLowerCase().contains(getText().toLowerCase()))
.collect(Collectors.toList());
searchResult.addAll(fitleredEntries)
Kindly suggest.

You can use a for loop:
for (String e : entries) {
if (e.toLowerCase().contains(getText().toLowerCase())) {
searchResult.add(e);
}
}

Related

Java 7 to Java 8 using streams

Converting the below code from Java 7 to Java 8 using streams
Java 7:
if (Objects.nonNull(input.getList())) {
if (Objects.nonNull(input.getId()) && !input.getList().contains(input.getId())) {
input.getList().add(input.getId());
}
} else if (Objects.nonNull(input.getId())) {
List<Long> ids = new ArrayList<>();
ids.add(input.getId());
input.setList(ids);
}
I tried something like this but it does not work properly.
Java 8
Stream.concat(input.getList().stream(),
input.getList().stream().filter(list2 -> !input.getList().contains(input.getId())));
Input class has two fields List<Long> list and Long id
Can someone please correct where I am missing.

Java 8 Streams: how can i stream another stream.How can i convert the code into java8 streams

Can someone please help me convert the below statements to Java8:
I have a hashmap like this:
private Map<String, Pair<List<XYZFiles>, List<XYZFiles>>> someMap;
I want to convert the below logic in java8:
private String searchFiles(String transmittedFileId) {
for (Pair<List<XYZFiles>, List<XYZFiles>> pair : someMap.values()) {
List<XYZFiles> createdFilesList = pair.getKey();
Optional<XYZFiles> xYZFiles= createdFilesList.stream()
.filter(file ->
file.getId().endsWith(transmittedFileId)).findFirst();
if (xYZFiles.isPresent()) {
return xYZFiles.get().getOriginId();
}
}
}
return someMap.values().stream()
.map(Pair::getKey)
.flatMap(List::stream)
.filter(file ->
file.getId().endsWith(transmittedFileId)
).findFirst().map(XYZFiles::getOriginId).orElse(null);
I think that should do it. It basically does it flat map, which flattens all those lists into one big stream and filters the whole thing.

map from string to multiple different strings and add to list with Java stream

I'm new to Java 8 and Streams .
I got a PolicyDefinition object, that got to two method : getAlias,getName which both returns a string .
Is there an elegant way to create a list with all aliases and names of policy definitions using Stream (created from collection of PolicyDefinition) in one statement ?
with two statements its not a problem :
List<String> policyNames =
policyDefinitions.stream()
.map(definition -> definition.getName())
.collect(Collectors.toList());
List<String> policyAlias =
policyDefinitions.stream()
.map(definition -> definition.getAlias())
.collect(Collectors.toList());
But Is it possible in one ?
Thanks a lot for the help
flatMap it!
List<String> policyNames = policyDefinitions.stream()
.flatMap(definition -> Stream.of(definition.getName(), definition.getAlias()))
.collect(Collectors.toList());
As mentioned in the comments - for tidyness, create a method in Definition
public Stream<String> allNames() {
return Stream.of(getName(), getAlias())
}
Then
List<String> policyNames = policyDefinitions.stream()
.flatMap(Definition::allNames)
.collect(Collectors.toList());
OP comments "I forgot to mention that getAlias might be null, what do you do than[sic]"
In that case, use Optional:
public Stream<String> allNames() {
return Stream.concat(Stream.of(getName()), Optional.ofNullable(getAlias()).stream())
}
Also you can create a Map with Alias as a Key and Name as a Value using groupingBuy operator

Java 8 map compute with set as value

My map looks like this
private Map<String, LinkedHashSet<String>> map = new HashMap<>();
in traditional approach I can add value to map with key check as below
public void addEdge(String node1, String node2) {
LinkedHashSet<String> adjacent = map.get(node1);
if (adjacent == null) {
adjacent = new LinkedHashSet();
map.put(node1, adjacent);
}
adjacent.add(node2);
}
with java 8, I can do something like this, with this one also I'm getting same output.
map.compute(node1, (k,v)-> {
if(v==null) {
v=new LinkedHashSet<>();
}
v.add(node2);
return v;
});
is there any better way to do with java 8?
Use
map.computeIfAbsent(node1, k -> new LinkedHashSet<>()).add(node2);
If node1 is already found in the map, it will be equivalent to:
map.get(node1).add(node2);
If node1 is not already in the map, it will be equivalent to:
map.put(node1, new LinkedHashSet<>()).add(node2);
This is exactly what you're looking for, and is even described as a use case in the documentation.
you can also use
map.merge(node1,new LinkedHashSet<>(),(v1,v2)->v1!=null?v1:v2).add(node2);
and also
map.compute(node1,(k,v)->v!=null?v:new LinkedHashSet<>()).add(node2);

How can I collect a Java 8 stream into a Guava ImmutableCollection?

I would like to do the following:
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());
but in a way that the resulting list is an implementation of Guava's ImmutableList.
I know I could do
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());
List<Integer> immutableList = ImmutableList.copyOf(list);
but I would like to collect to it directly. I've tried
List<Integer> list = IntStream.range(0, 7)
.collect(Collectors.toCollection(ImmutableList::of));
but it threw an exception:
java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:96)
The toImmutableList() method in the accepted answer of Alexis is now included in Guava 21 and can be used as:
ImmutableList<Integer> list = IntStream.range(0, 7)
.boxed()
.collect(ImmutableList.toImmutableList());
Edit: Removed #Beta from ImmutableList.toImmutableList along with other frequently used APIs in Release 27.1 (6242bdd).
This is where the collectingAndThen collector is useful:
List<Integer> list = IntStream.range(0, 7).boxed()
.collect(collectingAndThen(toList(), ImmutableList::copyOf));
It applies the transformation to the List you just built; resulting in an ImmutableList.
Or you could directly collect into the Builder and call build() at the end:
List<Integer> list = IntStream.range(0, 7)
.collect(Builder<Integer>::new, Builder<Integer>::add, (builder1, builder2) -> builder1.addAll(builder2.build()))
.build();
If this option is a bit-verbose to you and you want to use it in many places, you can create your own collector:
class ImmutableListCollector<T> implements Collector<T, Builder<T>, ImmutableList<T>> {
#Override
public Supplier<Builder<T>> supplier() {
return Builder::new;
}
#Override
public BiConsumer<Builder<T>, T> accumulator() {
return (b, e) -> b.add(e);
}
#Override
public BinaryOperator<Builder<T>> combiner() {
return (b1, b2) -> b1.addAll(b2.build());
}
#Override
public Function<Builder<T>, ImmutableList<T>> finisher() {
return Builder::build;
}
#Override
public Set<Characteristics> characteristics() {
return ImmutableSet.of();
}
}
and then:
List<Integer> list = IntStream.range(0, 7)
.boxed()
.collect(new ImmutableListCollector<>());
Just in case the link disappears in the comments; my second approach could be defined in a static utility method that simply uses Collector.of. It's simpler than creating your own Collector class.
public static <T> Collector<T, Builder<T>, ImmutableList<T>> toImmutableList() {
return Collector.of(Builder<T>::new, Builder<T>::add, (l, r) -> l.addAll(r.build()), Builder<T>::build);
}
and the usage:
List<Integer> list = IntStream.range(0, 7)
.boxed()
.collect(toImmutableList());
While not a direct answer to my question (it does not use collectors), this is a fairly elegant approach which doesn't use intermediate collections:
Stream<Integer> stream = IntStream.range(0, 7).boxed();
List<Integer> list = ImmutableList.copyOf(stream.iterator());
Source.
BTW: since JDK 10 it can be done in pure Java:
List<Integer> list = IntStream.range(0, 7)
.collect(Collectors.toUnmodifiableList());
Also toUnmodifiableSet and toUnmodifiableMap available.
Inside collector it was done via List.of(list.toArray())
FYI, there's a reasonable way to do this in Guava without Java 8:
ImmutableSortedSet<Integer> set = ContiguousSet.create(
Range.closedOpen(0, 7), DiscreteDomain.integers());
ImmutableList<Integer> list = set.asList();
If you don't actually need the List semantics and can just use a NavigableSet, that's even better since a ContiguousSet doesn't have to actually store all the elements in it (just the Range and DiscreteDomain).

Resources