why am i getting incompatible types error in RecyclerView - android-recyclerview

I've been dealing with this problem for a long time this is my error
error: incompatible types: androidx.recyclerview.widget.RecyclerView cannot be converted to android.support.v7.widget.RecyclerView
new RecyclerView_Config().setConfig(mRecyclerView,MainActivity.this,
this is where i got the error
public void DataIsLoaded(List<Book> books, List<String> keys) {
new RecyclerView_Config().setConfig(mRecyclerView,MainActivity.this,
books , keys);
^

Related

How to map a List to a Set while applying a method(Java to Kotlin code conversion)?

I have this code snippet in Java (this is an MCVE; actual code is more complex but has exact same issue):
enum StatusEnum { A, B, C; }
[...]
final static Set<String> names = Arrays.asList(StatusEnum.values())
.stream().map(StatusEnum::name).collect(Collectors.toSet());
IntelliJ gave me the following automated conversion to Kotlin:
internal val names = Arrays.asList(*StatusEnum.values())
.stream().map<String>(Function<StatusEnum, String> { it.name })
.collect<Set<String>, Any>(Collectors.toSet())
This unfortunately has compile errors:
Interface Function does not have constructors
Type inference failed. Expected type mismatch: inferred type is Collector!>! but Collector!>! was expected
Unresolved reference: it
This is my very first attempt at converting some code to Kotlin. I have reviewed the Functions and Lambdas section of the documentation. Still not clear what's going on here or how to fix it.
Use Kotlin methods instead of Java streams:
val names = StatusEnum.values()
.map { it.name }
.toSet()

type inference failed in Kotlin fun

translate a springboot java demo into a kotlin one,and run into a type inference failed problem.
it is a repository fun to get back the target result
package tacocloud.data
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Repository
import tacocloud.Ingredient
import tacocloud.Type
import java.sql.ResultSet
import java.sql.SQLException
#Repository
class JdbcIngredientRepository
#Autowired
constructor( private val jdbc: JdbcTemplate) : IngredientRepository {
override fun findAll(): Iterable<Ingredient> {
return jdbc.query("select id, name, type from Ingredient"
) { rs, rowNum -> this.mapRowToIngredient(rs, rowNum) }
}
override fun findById(id: String): Ingredient {
return jdbc.queryForObject(
"select id, name, type from Ingredient where id=?",
{ rs, rowNum -> mapRowToIngredient(rs, rowNum)}, arrayOf(id))
}
#Throws(SQLException::class)
private fun mapRowToIngredient(rs: ResultSet, rowNum: Int): Ingredient {
return Ingredient(
rs.getString("id"),
rs.getString("name"),
Type.valueOf(rs.getString("type")))
}
override fun save(ingredient: Ingredient): Ingredient {
jdbc.update(
"insert into Ingredient (id, name, type) values (?, ?, ?)",
ingredient.id,
ingredient.name,
ingredient.type.toString())
return ingredient
}
}
the findById funtion keeps saying that "Error:(29, 21) Kotlin: Type inference failed. Expected type mismatch: inferred type is Ingredient? but Ingredient was expected".the delegate funtion mapRowToIngredient(rs: ResultSet, rowNum: Int): Ingredient has return a Ingredient,not a Ingredient?
any ideas?
List item
JdbcTemplate, I suppose, is being compiled from Java source code file, and in Java any reference can point to null. That's why queryForObject returns a nullable type - Kotlin tends to treat all Java's references return declarations to be nullable (refer to "platform types" for more info).
And if queryForObject returns null, then the mapper function you provide will be just omitted and null will be returned from the function eventually.
It is possible to either make findById function return a nullable type (change the declaration so that it returns an Ingredient?), specify a default object to return if queryForObject returned null (e.g. jdbc.queryForObject(...) ?: DEFAULT_RESPONSE) or make use of force "unboxing" to the non-null type (e.g. jdbc.queryForObject(...)!!).
P.S.: it is quite common to get an empty response by id querying (e.g. an item by this id was deleted or so) and repositories often return nullable type or throw an exception in such a case, so personally I'd stick to this solution. But if your design guarantees that an item always be present when queried by id, I'd use the !! to cast nullable type to non-nullable by force.

Kotlin Iterable not supported in Apache Beam?

Apache beam seems to be refusing to recognise Kotlin's Iterable. Here is a sample code:
#ProcessElement
fun processElement(
#Element input: KV<String, Iterable<String>>, receiver: OutputReceiver<String>
) {
val output = input.key + "|" + input.value.toString()
println("output: $output")
receiver.output(output)
}
I get the following weird error:
java.lang.IllegalArgumentException:
...PrintString, #ProcessElement processElement(KV, OutputReceiver), #ProcessElement processElement(KV, OutputReceiver):
#Element argument must have type org.apache.beam.sdk.values.KV<java.lang.String, java.lang.Iterable<? extends java.lang.String>>
Sure enough, if I replace Iterable with java.lang.Iterable, the same code works just fine. What am I doing wrong?
Version of depedencies:
kotlin-jvm: 1.3.21
org.apache.beam: 2.11.0
Here is a gist with full codes and stack trace:
https://gist.github.com/marcoslin/e1e19afdbacac9757f6974592cfd8d7f#file-apache-beam-iterable-notworking-kt
Update:
After a bit of trial and error, I found out that while List<String> throws similar exception but MutableList<String> actually works:
class PrintString: DoFn<KV<String, MutableList<String>>, String>() {
#ProcessElement
fun processElement(
#Element input: KV<String, MutableList<String>>, receiver: OutputReceiver<String>
) {
val output = input.key + "|" + input.value.toString()
println("output: $output")
receiver.output(output)
}
}
So, this reminded me that Kotlin's Immutable collection are actually only interface and that underlying collection is still mutable. However, attempt to replace Iterable with MutableIterable continue to raise the error.
Update 2:
I deployed my Kotlin Dataflow job using the MutableList per above and job failed with:
java.lang.RuntimeException: org.apache.beam.sdk.util.UserCodeException: java.lang.ClassCastException:
org.apache.beam.runners.dataflow.worker.util.BatchGroupAlsoByWindowViaIteratorsFn$WindowReiterable cannot be cast to java.util.List
at org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)
at org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowFnRunner$1.outputWindowedValue(GroupAlsoByWindowFnRunner.java:102)
I had to switch back to use java.lang.Iterable.
I ran into this problem as well, when using a ParDo following a GroupByKey. It turns out that a #JvmWildcard annotation is needed in the Iterable generic type when writing a transformation that accepts the result of a GroupByKey.
See the contrived example below that reads a file and groups by the first character of each line.
class BeamPipe {
class ConcatLines : DoFn<KV<String, Iterable<#JvmWildcard String>>, KV<String, String>>() {
#ProcessElement
fun processElement(#Element input: KV<String, Iterable<#JvmWildcard String>>, receiver: OutputReceiver<KV<String, String>>) {
receiver.output(KV.of(input.key, input.value.joinToString("\n")))
}
}
fun pipe(options: PipelineOptions) {
val file =
"testFile.txt"
val p = Pipeline.create(options)
p.apply(TextIO.read().from(file))
.apply("Key lines by first character",
WithKeys.of { line: String -> line[0].toString() }
.withKeyType(TypeDescriptors.strings()))
.apply("Group lines by first character", GroupByKey.create<String, String>())
.apply("Concatenate lines", ParDo.of(ConcatLines()))
.apply("Write to files", FileIO.writeDynamic<String, KV<String, String>>()
.by { it.key }
.withDestinationCoder(StringUtf8Coder.of())
.via(Contextful.fn(ProcessFunction { it.value }), TextIO.sink())
.to("whatever")
.withNaming { key -> FileIO.Write.defaultNaming(key, ".txt") }
)
p.run()
}
}
This looks like a bug in the Beam Kotlin SDK. The Reflection analysis for your #ProcessElement method does not work correctly. You can probably work around this by using ProcessContext ctx instead of using the #Element parameter.
I am not very familiar with kotlin but it seems that you need to import import java.lang.Iterable before using it in your code.
May I know how to fix the issue when we get the iterable from groupbykey.create(). i could not groupbykey as you did javalang iterable
For those are experiencing this issue and found their way here, my current workaround to keep writing the pipeline in kotlin is to create a Java static class with function(s) that creates, contains, and processes your Iterable(s). The result (in non-iterable format) can then be passed back to the kotlin.

How do I access / manipulate an element within a Flux / Mono

I need to access a method inside a class, which is inside the Mono. How do I do this?
I have:
public Mono<LegalPerson> find(Long id) {
return Optional.of(repository.findById(id)).orElseThrow(() -> new UserNotFoundException("Error"));
}
And here is my problem:
public void update(Mono<LegalPerson> legalPersonJson) {
var legalPersonDB = find(legalPersonJson.map(legalPerson -> legalPerson.getId()));
I am getting the following error:
Incompatible types. Required Long but 'map' was inferred to Mono<R>: no instance(s) of type variable(s) R exist so that Mono<R> conforms to Long
This is what you need to do
Mono<Long> legalPersonDB = legalPersonJson.map(legalPerson -> find(legalPerson.getId()))
You will still need to subscribe to the Mono in order for it to execute.

How to handle nullable generics with Java interop

I have a Java class that is out of my control, defined as:
public #interface ValueSource {
String[] strings() default {}
}
I am trying to use this class from a Kotlin file I control, like so:
class Thing {
#ValueSource(string = ["non-null", null])
fun performAction(value: String?) {
// Do stuff
}
}
I get a compiler error
Kotlin: Type inference failed. Expected type mismatch: inferred type is Array<String?> but Array<String> was expected.
I understand why the inferred type is Array<String?>, but why is the expected type not the same? Why is Kotlin interpreting the Java generic as String! rather than String?? And finally, is there a way to suppress the error?
Kotlin 1.2.61
This isn't a Kotlin issue - this code isn't valid either, because Java simply doesn't allow null values in annotation parameters:
public class Thing {
#ValueSource(strings = {"non-null", null}) // Error: Attribute value must be constant
void performAction(String value) {
// Do stuff
}
}
See this article and this question for more discussion on this.