How do I can convert Scala for loop into Java - java

Here are some lines of code that need to convert into Java.
val geojsonSeq = for (kml <- kmlSeq) yield kmlConverter.toGeoJson(kml)
I tried to convert using for each loop in java using lamda operator but not able to get it.
kmlSeq.foreach((Function1<Option<Kml>, U>) (f) -> {
});
Every time I am getting compile-time error like:
"The method foreach(Function1<Option,U>) is ambiguous for the type Seq<Option>"
Apart from this if I'm going to use normally for each loop in java like :
for(Option<Kml> kml : kmlSeq)
{
}
In that case kmlSeq is throwing error like :
"Can only iterate over an array or an instance of java.lang.Iterable"
But in scala the kmlSeq looping into Option object.

You can use either of two ways (Assuming return type of toGeoJson is String)
List<String> result = kmlSeq
.stream()
.flatMap(kmlOpt ->
kmlOpt.map(Stream::of).orElseGet(Stream::empty)
)
.map(kml -> kmlConverter.toGeoJson(kml))
.collect(Collectors.toList());
or
List<String> result = kmlSeq
.stream()
.flatMap(kmlOpt ->
kmlOpt.map(kml ->
Stream.of(kmlConverter.toGeoJson(kml))
).orElseGet(Stream::empty)
)
.collect(Collectors.toList());
To print, do this
result.forEach(System.out::println);

Related

Converting nested optional list to optional list in Java?

I have an optionalIdList ( Optional<Set<String>> optionalIdList) that I want to iterate over, and then convert back to Optional<Set<String>>. My code thus far is like this:
optionalIdList
.map(
idList ->
idList.stream()
.map(
id ->
filterIds(
partnerIds
)))
.flatMap(streamOfLists -> streamOfLists.map(item -> item.orElseGet(ImmutableSet::of)));
The filterIds list returns Optional<Set<String>>
However with my current solution I get the following error:
Required type: Optional<Set<String>>
Provided: Optional<Object>
Is there a nice way to do what I want to do?
EDIT: For some reason I assumed filterIds returns a single String, and not an Optional<Set<String>> as you wrote it does.
Here's the updated answer:
Optional<Set<String>> output =
optionalIdList.map(idList -> idList.stream()
.map(id -> filterIds(partnerIds))
.filter (Optional::isPresent)
.map (Optional::get)
.flatMap (Set::stream)
.collect(Collectors.toSet()));

Getting Incompatible types error while trying to map a list

I have a FeeAccount list that I would like to fill. I want to use .stream.map() to get it done. What I've managed to do is to make a method that would map my list and return it. I've written this code using some other examples I have found online. My problem is that somehow it returns a list that is incompatible with List.
I am getting an error: Incompatible types. Required List but 'map' was inferred to Stream: no instance(s) of type variable(s) R exist so that Stream conforms to List
As I understand the problem is with the part where I use collect(Collectors.toList()). But I am not sure. I don't even clearly understand what the error message means.
Maybe someone can explain what am I doing wrong? Is it with the .stream.map()? Because I never used it before. Or maybe the problem is somewhere else.
Method(List<contract> contractList){
List<FeeAccount> feeAccounts = new ArrayList<>();
feeAccounts = contractList
.stream()
.map(contract -> {
List<Fee> monthlyFees=...;
return monthlyFees.stream()
.map(monthlyFee -> {
FeeAccount account = new FeeAccount();
account.setFeeCode(monthlyFee.getFeeCode());
account.setDebtorAccount(contract.getDebtorAccount());
return account;
}).collect(Collectors.toList());
});}
You have two nested map operations. The outer transforms a contract to a List<FeeAccount>, and the inner transforms a Fee to a FeeAccount.
Hence, your pipeline results in a Stream<List<FeeAccount>> without a terminal operation.
If you add a .collect(Collectors.toList()) in the end, you'll get a List<List<FeeAccount>>.
If you want to merge all those inner lists into a single output list, you should use flatMap.
To obtain a flat List:
List<FeeAccount> feeAccounts =
contractList.stream()
.flatMap(contract -> {
List<Fee> monthlyFees=...;
return monthlyFees.stream()
.map(monthlyFee -> {
FeeAccount account = new FeeAccount();
account.setFeeCode(monthlyFee.getFeeCode());
account.setDebtorAccount(contract.getDebtorAccount());
return account;
});
})
.collect(Collectors.toList();
map() is an intermediate operation in a stream pipeline (please look at Stream operations and pipelines), which means that it returns a stream.
feeAccounts = contractList
.stream()
.map(...) // result of this operation is Stream<<List<FeeAccount>>
and not a List<FeeAccount>
You are missing a terminal operation like .collect(Collectors.toList() :
List<FeeAccount> feeAccounts = contractList
.stream()
.flatMap(monthlyFees -> monthlyFees.stream()
.map(monthlyFee -> {
FeeAccount account = new FeeAccount();
account.setFeeCode(monthlyFee.getFeeCode());
account.setDebtorAccount(contract.getDebtorAccount());
return account;
})
.collect(Collectors.toList());
flatMap transforms Stream<Stream<FeeAccount>> into just Stream<FeeAccount>

Converting list object into custom Map using Java 8 stream object

I have a class "First" which contains reference to Class "Second" as list. I am trying to achieve below block in Java 8 way by using Stream (or) flap Map (or) groupingBy
foreach(First a: listOfFirst){
for (Second b: a.getSecondDetails()) {
inputMap.put(b, a);
}
}
I tried below simplified way
listOfFirst.stream()
.flatMap(p -> p.getSecondDetails().stream())
.collect(Collectors.toMap(p -> p, q -> q));
I am missing something here, please help me out
You need to "remember" the First instance corresponding to each Second instance. You can do it, for example, by creating Map.Entry instances:
Map<Second,First> result =
listOfFirst.stream()
.flatMap(p->p.getSecondDetails()
.stream()
.map(sec -> new SimpleEntry<>(sec,p))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue));

How to get all values from List of Map in Scala?

I have list of Map.
List(Map(term_id -> 20898477-2374-4d4c-9af0-8ed9c9829c94),
Map(term_id -> 6d949993-1593-4491-beae-eb9bf8abcf27),
Map(term_id -> 1123c413-3ffd-45ed-8215-dd1bccb3a48f))
and want to get all value and check if a term_id already exist in above list of Map.
This can be done with iterating list and checking value of each map. But I want something more efficient and one liner. I am okay with either of Java or Scala approach.
This question may be naive, but I am not getting at how to proceed. I am new to Java/Scala.
Expected Output:
List(20898477-2374-4d4c-9af0-8ed9c9829c94, 6d949993-1593-4491-beae-eb9bf8abcf27,
123c413-3ffd-45ed-8215-dd1bccb3a48f)
I think flatMap is what you want:
val maplist=List(Map("term_id" -> "20898477-2374-4d4c-9af0-8ed9c9829c94"), Map("term_id" -> "6d949993-1593-4491-beae-eb9bf8abcf27"), Map("term_id" -> "1123c413-3ffd-45ed-8215-dd1bccb3a48f"))
maplist.flatMap(_.values)
//res0: List[String] = List(20898477-2374-4d4c-9af0-8ed9c9829c94, 6d949993-1593-4491-beae-eb9bf8abcf27, 1123c413-3ffd-45ed-8215-dd1bccb3a48f)
maplist.flatMap(_.keys)
//res1: List[String] = List(term_id, term_id, term_id)
you can use below code to get list of values
val maplist=List(Map("term_id" -> "20898477-2374-4d4c-9af0-8ed9c9829c94"), Map("term_id" -> "6d949993-1593-4491-beae-eb9bf8abcf27"), Map("term_id" -> "1123c413-3ffd-45ed-8215-dd1bccb3a48f"))
maplist.map(x=>x.get("term_id")
Output:
List[Option[String]] = List(Some(20898477-2374-4d4c-9af0-8ed9c9829c94), Some(6d949993-1593-4491-beae-eb9bf8abcf27), Some(1123c413-3ffd-45ed-8215-dd1bccb3a48f))

Java - Find Element in Array using Condition and Lambda

In short, I have this code, and I'd like to get an specific element of the array using a condition and lambda. The code would be something like this:
Preset[] presets = presetDALC.getList();
Preset preset = Arrays.stream(presets).select(x -> x.getName().equals("MyString"));
But obviously this does not work. In C# would be something similar but in Java, how do I do this?
You can do it like this,
Optional<Preset> optional = Arrays.stream(presets)
.filter(x -> "MyString".equals(x.getName()))
.findFirst();
if(optional.isPresent()) {//Check whether optional has element you are looking for
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.
Do you want first matching, or all matching?
String[] presets = {"A", "B", "C", "D", "CA"};
// Find all matching
List<String> resultList = Arrays.stream(presets)
.filter(x -> x.startsWith("C"))
.collect(Collectors.toList());
System.out.println(resultList);
// Find first matching
String firstResult = Arrays.stream(presets)
.filter(x -> x.startsWith("C"))
.findFirst()
.orElse(null);
System.out.println(firstResult);
Output
[C, CA]
C
One-liner since Java 8:
Preset found = Stream.of(presets)
.filter(p -> p.getName().equals("MyString"))
.findFirst().orElseThrow();
Avoid declaring Optional<>, that returned from findFirst as a variable or a parameter. It is designed for return types / "one-liner" styles.
see javadoc API Note
see 26 Reasons Why Using Optional Correctly

Categories

Resources