TypeConverter 实现的索引越界错误
Index out of bound error with TypeConverter implementation
我正在尝试将此数据 class 保存到数据库中:
@Entity
@Parcelize
data class Rocket(
@SerializedName("active")
val active: Boolean = false,
@SerializedName("boosters")
val boosters: Int = 0,
@SerializedName("company")
val company: String = "",
@SerializedName("cost_per_launch")
val costPerLaunch: Int = 0,
@SerializedName("country")
val country: String = "",
@SerializedName("description")
val description: String = "",
@SerializedName("diameter")
val diameter: Diameter = Diameter(),
@SerializedName("engines")
val engines: Engines = Engines(),
@SerializedName("first_flight")
val firstFlight: String = "",
@SerializedName("first_stage")
val firstStage: FirstStage = FirstStage(),
@SerializedName("flickr_images")
val flickrImages: List<String> = listOf(),
@SerializedName("height")
val height: Height = Height(),
@PrimaryKey
@SerializedName("id")
val id: String = "",
@SerializedName("landing_legs")
val landingLegs: LandingLegs = LandingLegs(),
@SerializedName("mass")
val mass: Mass = Mass(),
@SerializedName("name")
val name: String = "",
@SerializedName("payload_weights")
val payloadWeights: List<PayloadWeight> = listOf(),
@SerializedName("second_stage")
val secondStage: SecondStage = SecondStage(),
@SerializedName("stages")
val stages: Int = 0,
@SerializedName("success_rate_pct")
val successRatePct: Int = 0,
@SerializedName("type")
val type: String = "",
@SerializedName("wikipedia")
val wikipedia: String = ""
): Parcelable
@Parcelize
data class Diameter(
@SerializedName("feet")
val feet: Double = 0.0,
@SerializedName("meters")
val meters: Double = 0.0
): Parcelable
@Parcelize
data class Engines(
@SerializedName("engine_loss_max")
val engineLossMax: Int = 0,
@SerializedName("isp")
val isp: Isp = Isp(),
@SerializedName("layout")
val layout: String = "",
@SerializedName("number")
val number: Int = 0,
@SerializedName("propellant_1")
val propellant1: String = "",
@SerializedName("propellant_2")
val propellant2: String = "",
@SerializedName("thrust_sea_level")
val thrustSeaLevel: ThrustSeaLevel = ThrustSeaLevel(),
@SerializedName("thrust_to_weight")
val thrustToWeight: Double = 0.0,
@SerializedName("thrust_vacuum")
val thrustVacuum: ThrustVacuum = ThrustVacuum(),
@SerializedName("type")
val type: String = "",
@SerializedName("version")
val version: String = ""
): Parcelable
@Parcelize
data class FirstStage(
@SerializedName("burn_time_sec")
val burnTimeSec: Int = 0,
@SerializedName("engines")
val engines: Int = 0,
@SerializedName("fuel_amount_tons")
val fuelAmountTons: Double = 0.0,
@SerializedName("reusable")
val reusable: Boolean = false,
@SerializedName("thrust_sea_level")
val thrustSeaLevel: ThrustSeaLevel = ThrustSeaLevel(),
@SerializedName("thrust_vacuum")
val thrustVacuum: ThrustVacuum = ThrustVacuum()
): Parcelable
@Parcelize
data class Height(
@SerializedName("feet")
val feet: Double = 0.0,
@SerializedName("meters")
val meters: Double = 0.0
): Parcelable {
fun toStringMetric(): String {
return "Height: $meters m"
}
fun toStringImperial(): String {
return "Height: $feet ft"
}
}
@Parcelize
data class LandingLegs(
@SerializedName("material")
val material: String = "",
@SerializedName("number")
val number: Int = 0
): Parcelable
@Parcelize
data class Mass(
@SerializedName("kg")
val kg: Int = 0,
@SerializedName("lb")
val lb: Int = 0
): Parcelable {
fun toStringMetric(): String {
return "Mass: $kg kg"
}
fun toStringImperial(): String {
return "Mass: $lb lbs"
}
}
@Parcelize
data class PayloadWeight(
@SerializedName("id")
val id: String = "",
@SerializedName("kg")
val kg: Int = 0,
@SerializedName("lb")
val lb: Int = 0,
@SerializedName("name")
val name: String = ""
): Parcelable
@Parcelize
data class SecondStage(
@SerializedName("burn_time_sec")
val burnTimeSec: Int = 0,
@SerializedName("engines")
val engines: Int = 0,
@SerializedName("fuel_amount_tons")
val fuelAmountTons: Double = 0.0,
@SerializedName("payloads")
val payloads: Payloads = Payloads(),
@SerializedName("reusable")
val reusable: Boolean = false,
@SerializedName("thrust")
val thrust: Thrust = Thrust()
): Parcelable
@Parcelize
data class Isp(
@SerializedName("sea_level")
val seaLevel: Int = 0,
@SerializedName("vacuum")
val vacuum: Int = 0
): Parcelable
@Parcelize
data class ThrustSeaLevel(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class ThrustVacuum(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class Payloads(
@SerializedName("composite_fairing")
val compositeFairing: CompositeFairing = CompositeFairing(),
@SerializedName("option_1")
val option1: String = ""
): Parcelable
@Parcelize
data class Thrust(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class CompositeFairing(
@SerializedName("diameter")
val diameter: Diameter = Diameter(),
@SerializedName("height")
val height: Height = Height()
): Parcelable
In order to do that, I have to write type converters that convert non-primitive types. My naive solution is to just convert everything into a string that's divided by `;`.
这是我写的:
class RocketTypeConverter {
@TypeConverter
fun fromDiameterToString(diam: Diameter?): String? {
return diam?.let {
"${diam.feet};${diam.meters}"
}
}
@TypeConverter
fun fromStringToDiameter(str: String?): Diameter? {
str?.let {
str.split(";").also {
return Diameter(
feet = it[0].toDouble(),
meters = it[1].toDouble()
)
}
}
return null
}
@TypeConverter
fun fromEnginesToString(engines: Engines?): String? {
engines?.let {
engines.apply {
return "$engineLossMax" +
";" + fromIspToString(isp) +
";" + layout +
";" + "$number" +
";" + propellant1 +
";" + propellant2 +
";" + fromThrustSeaLevelToString(thrustSeaLevel) +
";" + "$thrustToWeight" +
";" + fromThrustVacuumToString(thrustVacuum) +
";" + type +
";" + version
}
}
return null
}
@TypeConverter
fun fromStringToEngines(str: String?): Engines? {
str?.let {
str.split(";").also {
val isp = fromStringToIsp(it[1])
val thrustSeaLevel = fromStringToThrustSeaLevel(it[6])
val thrustVacuum = fromStringToThrustVacuum(it[8])
return if(isp != null && thrustSeaLevel != null && thrustVacuum != null) {
Engines(
engineLossMax = it[0].toInt(),
isp = isp,
layout = it[2],
number = it[3].toInt(),
propellant1 = it[4],
propellant2 = it[5],
thrustSeaLevel = thrustSeaLevel,
thrustToWeight = it[7].toDouble(),
thrustVacuum = thrustVacuum,
type = it[9],
version = it[10]
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromFirstStageToString(firstStage: FirstStage?): String? {
firstStage?.let {
firstStage.apply {
return "$burnTimeSec" +
";" + "$engines" +
";" + "$fuelAmountTons" +
";" + (if(reusable) "1" else "0") +
";" + fromThrustSeaLevelToString(thrustSeaLevel) +
";" + fromThrustVacuumToString(thrustVacuum)
}
}
return null
}
@TypeConverter
fun fromStringToFirstStage(str: String?): FirstStage? {
str?.let {
str.split(";").also {
val thrustSeaLevel = fromStringToThrustSeaLevel(it[4])
val thrustVacuum = fromStringToThrustVacuum(it[5])
return if(thrustSeaLevel != null && thrustVacuum != null) {
FirstStage(
burnTimeSec = it[0].toInt(),
engines = it[1].toInt(),
fuelAmountTons = it[2].toDouble(),
reusable = it[3] == "1",
thrustSeaLevel = thrustSeaLevel,
thrustVacuum = thrustVacuum
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromHeightToString(height: Height?): String? {
height?.let {
return "${height.feet};${height.meters}"
}
return null
}
@TypeConverter
fun fromStringToHeight(str: String?): Height? {
str?.let {
str.split(";").also {
return Height(
feet = it[0].toDouble(),
meters = it[1].toDouble()
)
}
}
return null
}
@TypeConverter
fun fromLadingLegsToString(landingLegs: LandingLegs?): String? {
landingLegs?.let {
return "${landingLegs.material};${landingLegs.number}"
}
return null
}
@TypeConverter
fun fromStringToLandingLegs(str: String?): LandingLegs? {
str?.let {
str.split(";").also {
return LandingLegs(
material = it[0],
number = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromMassToString(mass: Mass?): String? {
mass?.let {
return "${mass.kg};${mass.lb}"
}
return null
}
@TypeConverter
fun fromStringToMass(str: String?): Mass? {
str?.let {
str.split(";").also {
return Mass(
kg = it[0].toInt(),
lb = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromPayLoadWeightToString(payloadWeight: PayloadWeight?): String? {
payloadWeight?.let {
return "${payloadWeight.id};${payloadWeight.kg};${payloadWeight.lb};${payloadWeight.name}"
}
return null
}
@TypeConverter
fun fromStringToPayloadWeight(str: String?): PayloadWeight? {
str?.let {
str.split(";").also {
return PayloadWeight(
id = it[0],
kg = it[1].toInt(),
lb = it[2].toInt(),
name = it[3]
)
}
}
return null
}
@TypeConverter
fun fromSecondStageToString(secondStage: SecondStage?): String? {
secondStage?.let {
secondStage.apply {
return "$burnTimeSec" +
";" + "$engines" +
";" + "$fuelAmountTons" +
";" + fromPayloadsToString(payloads) +
";" + (if(reusable) "1" else "0") +
";" + fromThrustToString(thrust)
}
}
return null
}
@TypeConverter
fun fromStringToSecondStage(str: String?): SecondStage? {
str?.let {
str.split(";").also {
val payloads = fromStringToPayloads(it[3])
val thrust = fromStringToThrust(it[5])
return if(payloads != null && thrust != null) {
return SecondStage(
burnTimeSec = it[0].toInt(),
engines = it[1].toInt(),
fuelAmountTons = it[2].toDouble(),
payloads = payloads,
reusable = it[4] == "1",
thrust = thrust
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromThrustToString(thrust: Thrust?): String? {
thrust?.let {
return "${thrust.kN};${thrust.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrust(str: String?): Thrust? {
str?.let {
str.split(";").also {
return Thrust(
kN = it[0].toInt(),
lbf = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromPayloadsToString(payloads: Payloads?): String? {
payloads?.let {
return fromCompositeFairingToString(payloads.compositeFairing) + payloads.option1
}
return null
}
@TypeConverter
fun fromStringToPayloads(str: String?): Payloads? {
str?.let {
str.split(";").also {
fromStringToCompositeFairing(it[0])?.let { compositeFairing ->
return Payloads(
compositeFairing = compositeFairing,
option1 = it[1]
)
} ?: return null
}
}
return null
}
@TypeConverter
fun fromCompositeFairingToString(compositeFairing: CompositeFairing?): String? {
compositeFairing?.let {
return fromDiameterToString(compositeFairing.diameter) +
fromHeightToString(compositeFairing.height)
}
return null
}
@TypeConverter
fun fromStringToCompositeFairing(str: String?): CompositeFairing? {
str?.let {
str.split(";").also {
val diameter = fromStringToDiameter(it[0])
val height = fromStringToHeight(it[1])
return if(diameter != null && height != null) {
CompositeFairing(
diameter = diameter,
height = height
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromIspToString(isp: Isp?): String? {
isp?.let {
return "${isp.seaLevel};${isp.vacuum}"
}
return null
}
@TypeConverter
fun fromStringToIsp(str: String?): Isp? {
str?.let {
str.split(";").also {
return Isp(
seaLevel = it[0].toInt(),
vacuum = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromThrustSeaLevelToString(thrustSeaLevel: ThrustSeaLevel?): String? {
thrustSeaLevel?.let {
return "${thrustSeaLevel.kN};${thrustSeaLevel.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrustSeaLevel(str: String?): ThrustSeaLevel? {
str?.let {
str.split(";").also {
return ThrustSeaLevel(
kN = str[0].toInt(),
lbf = str[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromThrustVacuumToString(thrustVacuum: ThrustVacuum?): String? {
thrustVacuum?.let {
return "${thrustVacuum.kN};${thrustVacuum.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrustVacuum(str: String?): ThrustVacuum? {
str?.let {
str.split(";").also {
return ThrustVacuum(
kN = str[0].toInt(),
lbf = str[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromFlickrImagesToString(flickrImages: List<String>?): String? {
flickrImages?.let {
var imagesString = ""
for(image in flickrImages) {
imagesString += "$image;"
}
return imagesString.substring(0, (imagesString.length - 1))
}
return null
}
@TypeConverter
fun fromStringToFlickrImages(str: String?): List<String>? {
str?.let {
return str.split(";")
}
return null
}
@TypeConverter
fun fromPayloadWeightsToString(payloadWeights: List<PayloadWeight>?): String? {
payloadWeights?.let {
var weightsString = ""
for(weight in payloadWeights) {
weightsString += fromPayLoadWeightToString(weight) + ";"
}
return weightsString.substring(0, (weightsString.length - 1))
}
return null
}
@TypeConverter
fun fromStringToPayloadWeights(str: String?): List<PayloadWeight>? {
str?.let {
val weights = mutableListOf<PayloadWeight>()
str.split(";").also {
for(payloadWeight in it) {
fromStringToPayloadWeight(payloadWeight)?.let { payloadWeight ->
weights.add(payloadWeight)
} ?: return null
}
}
return weights
}
return null
}
}
我的方法是有两个模块:launch
和 rocket
。每个都有自己的存储库,每个存储库都构建数据库:
private val dao: Database = Room.databaseBuilder(
context,
Database::class.java,
Database.NAME_DB
).build()
我遇到的问题是出现此错误:java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
。
现在,错误发生是因为 fromStringToIsp()
。这看起来不像是算法错误,因为 Isp
class 只有两个字段,所以我不会在索引上出错。如果我强行通过fromStringToIsp()
,其他一些函数也会报告越界错误。
那么我在实施 TypeConverters
时哪里出错了?
您传递给 fromStringToIsp()
的字符串不包含分号,因为在 fromStringToEngines()
中您正在执行以下操作:
str.split(";").also {
val isp = fromStringToIsp(it[1])
/* ... */
}
然后,在 fromStringToIsp()
中,您执行:
str.split(";").also {
return Isp(
seaLevel = it[0].toInt(),
vacuum = it[1].toInt()
)
}
当试图访问 it[1]
时你会得到一个异常,因为 it
只有一个元素,即 it[0]
.
我正在尝试将此数据 class 保存到数据库中:
@Entity
@Parcelize
data class Rocket(
@SerializedName("active")
val active: Boolean = false,
@SerializedName("boosters")
val boosters: Int = 0,
@SerializedName("company")
val company: String = "",
@SerializedName("cost_per_launch")
val costPerLaunch: Int = 0,
@SerializedName("country")
val country: String = "",
@SerializedName("description")
val description: String = "",
@SerializedName("diameter")
val diameter: Diameter = Diameter(),
@SerializedName("engines")
val engines: Engines = Engines(),
@SerializedName("first_flight")
val firstFlight: String = "",
@SerializedName("first_stage")
val firstStage: FirstStage = FirstStage(),
@SerializedName("flickr_images")
val flickrImages: List<String> = listOf(),
@SerializedName("height")
val height: Height = Height(),
@PrimaryKey
@SerializedName("id")
val id: String = "",
@SerializedName("landing_legs")
val landingLegs: LandingLegs = LandingLegs(),
@SerializedName("mass")
val mass: Mass = Mass(),
@SerializedName("name")
val name: String = "",
@SerializedName("payload_weights")
val payloadWeights: List<PayloadWeight> = listOf(),
@SerializedName("second_stage")
val secondStage: SecondStage = SecondStage(),
@SerializedName("stages")
val stages: Int = 0,
@SerializedName("success_rate_pct")
val successRatePct: Int = 0,
@SerializedName("type")
val type: String = "",
@SerializedName("wikipedia")
val wikipedia: String = ""
): Parcelable
@Parcelize
data class Diameter(
@SerializedName("feet")
val feet: Double = 0.0,
@SerializedName("meters")
val meters: Double = 0.0
): Parcelable
@Parcelize
data class Engines(
@SerializedName("engine_loss_max")
val engineLossMax: Int = 0,
@SerializedName("isp")
val isp: Isp = Isp(),
@SerializedName("layout")
val layout: String = "",
@SerializedName("number")
val number: Int = 0,
@SerializedName("propellant_1")
val propellant1: String = "",
@SerializedName("propellant_2")
val propellant2: String = "",
@SerializedName("thrust_sea_level")
val thrustSeaLevel: ThrustSeaLevel = ThrustSeaLevel(),
@SerializedName("thrust_to_weight")
val thrustToWeight: Double = 0.0,
@SerializedName("thrust_vacuum")
val thrustVacuum: ThrustVacuum = ThrustVacuum(),
@SerializedName("type")
val type: String = "",
@SerializedName("version")
val version: String = ""
): Parcelable
@Parcelize
data class FirstStage(
@SerializedName("burn_time_sec")
val burnTimeSec: Int = 0,
@SerializedName("engines")
val engines: Int = 0,
@SerializedName("fuel_amount_tons")
val fuelAmountTons: Double = 0.0,
@SerializedName("reusable")
val reusable: Boolean = false,
@SerializedName("thrust_sea_level")
val thrustSeaLevel: ThrustSeaLevel = ThrustSeaLevel(),
@SerializedName("thrust_vacuum")
val thrustVacuum: ThrustVacuum = ThrustVacuum()
): Parcelable
@Parcelize
data class Height(
@SerializedName("feet")
val feet: Double = 0.0,
@SerializedName("meters")
val meters: Double = 0.0
): Parcelable {
fun toStringMetric(): String {
return "Height: $meters m"
}
fun toStringImperial(): String {
return "Height: $feet ft"
}
}
@Parcelize
data class LandingLegs(
@SerializedName("material")
val material: String = "",
@SerializedName("number")
val number: Int = 0
): Parcelable
@Parcelize
data class Mass(
@SerializedName("kg")
val kg: Int = 0,
@SerializedName("lb")
val lb: Int = 0
): Parcelable {
fun toStringMetric(): String {
return "Mass: $kg kg"
}
fun toStringImperial(): String {
return "Mass: $lb lbs"
}
}
@Parcelize
data class PayloadWeight(
@SerializedName("id")
val id: String = "",
@SerializedName("kg")
val kg: Int = 0,
@SerializedName("lb")
val lb: Int = 0,
@SerializedName("name")
val name: String = ""
): Parcelable
@Parcelize
data class SecondStage(
@SerializedName("burn_time_sec")
val burnTimeSec: Int = 0,
@SerializedName("engines")
val engines: Int = 0,
@SerializedName("fuel_amount_tons")
val fuelAmountTons: Double = 0.0,
@SerializedName("payloads")
val payloads: Payloads = Payloads(),
@SerializedName("reusable")
val reusable: Boolean = false,
@SerializedName("thrust")
val thrust: Thrust = Thrust()
): Parcelable
@Parcelize
data class Isp(
@SerializedName("sea_level")
val seaLevel: Int = 0,
@SerializedName("vacuum")
val vacuum: Int = 0
): Parcelable
@Parcelize
data class ThrustSeaLevel(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class ThrustVacuum(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class Payloads(
@SerializedName("composite_fairing")
val compositeFairing: CompositeFairing = CompositeFairing(),
@SerializedName("option_1")
val option1: String = ""
): Parcelable
@Parcelize
data class Thrust(
@SerializedName("kN")
val kN: Int = 0,
@SerializedName("lbf")
val lbf: Int = 0
): Parcelable
@Parcelize
data class CompositeFairing(
@SerializedName("diameter")
val diameter: Diameter = Diameter(),
@SerializedName("height")
val height: Height = Height()
): Parcelable
In order to do that, I have to write type converters that convert non-primitive types. My naive solution is to just convert everything into a string that's divided by `;`.
这是我写的:
class RocketTypeConverter {
@TypeConverter
fun fromDiameterToString(diam: Diameter?): String? {
return diam?.let {
"${diam.feet};${diam.meters}"
}
}
@TypeConverter
fun fromStringToDiameter(str: String?): Diameter? {
str?.let {
str.split(";").also {
return Diameter(
feet = it[0].toDouble(),
meters = it[1].toDouble()
)
}
}
return null
}
@TypeConverter
fun fromEnginesToString(engines: Engines?): String? {
engines?.let {
engines.apply {
return "$engineLossMax" +
";" + fromIspToString(isp) +
";" + layout +
";" + "$number" +
";" + propellant1 +
";" + propellant2 +
";" + fromThrustSeaLevelToString(thrustSeaLevel) +
";" + "$thrustToWeight" +
";" + fromThrustVacuumToString(thrustVacuum) +
";" + type +
";" + version
}
}
return null
}
@TypeConverter
fun fromStringToEngines(str: String?): Engines? {
str?.let {
str.split(";").also {
val isp = fromStringToIsp(it[1])
val thrustSeaLevel = fromStringToThrustSeaLevel(it[6])
val thrustVacuum = fromStringToThrustVacuum(it[8])
return if(isp != null && thrustSeaLevel != null && thrustVacuum != null) {
Engines(
engineLossMax = it[0].toInt(),
isp = isp,
layout = it[2],
number = it[3].toInt(),
propellant1 = it[4],
propellant2 = it[5],
thrustSeaLevel = thrustSeaLevel,
thrustToWeight = it[7].toDouble(),
thrustVacuum = thrustVacuum,
type = it[9],
version = it[10]
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromFirstStageToString(firstStage: FirstStage?): String? {
firstStage?.let {
firstStage.apply {
return "$burnTimeSec" +
";" + "$engines" +
";" + "$fuelAmountTons" +
";" + (if(reusable) "1" else "0") +
";" + fromThrustSeaLevelToString(thrustSeaLevel) +
";" + fromThrustVacuumToString(thrustVacuum)
}
}
return null
}
@TypeConverter
fun fromStringToFirstStage(str: String?): FirstStage? {
str?.let {
str.split(";").also {
val thrustSeaLevel = fromStringToThrustSeaLevel(it[4])
val thrustVacuum = fromStringToThrustVacuum(it[5])
return if(thrustSeaLevel != null && thrustVacuum != null) {
FirstStage(
burnTimeSec = it[0].toInt(),
engines = it[1].toInt(),
fuelAmountTons = it[2].toDouble(),
reusable = it[3] == "1",
thrustSeaLevel = thrustSeaLevel,
thrustVacuum = thrustVacuum
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromHeightToString(height: Height?): String? {
height?.let {
return "${height.feet};${height.meters}"
}
return null
}
@TypeConverter
fun fromStringToHeight(str: String?): Height? {
str?.let {
str.split(";").also {
return Height(
feet = it[0].toDouble(),
meters = it[1].toDouble()
)
}
}
return null
}
@TypeConverter
fun fromLadingLegsToString(landingLegs: LandingLegs?): String? {
landingLegs?.let {
return "${landingLegs.material};${landingLegs.number}"
}
return null
}
@TypeConverter
fun fromStringToLandingLegs(str: String?): LandingLegs? {
str?.let {
str.split(";").also {
return LandingLegs(
material = it[0],
number = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromMassToString(mass: Mass?): String? {
mass?.let {
return "${mass.kg};${mass.lb}"
}
return null
}
@TypeConverter
fun fromStringToMass(str: String?): Mass? {
str?.let {
str.split(";").also {
return Mass(
kg = it[0].toInt(),
lb = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromPayLoadWeightToString(payloadWeight: PayloadWeight?): String? {
payloadWeight?.let {
return "${payloadWeight.id};${payloadWeight.kg};${payloadWeight.lb};${payloadWeight.name}"
}
return null
}
@TypeConverter
fun fromStringToPayloadWeight(str: String?): PayloadWeight? {
str?.let {
str.split(";").also {
return PayloadWeight(
id = it[0],
kg = it[1].toInt(),
lb = it[2].toInt(),
name = it[3]
)
}
}
return null
}
@TypeConverter
fun fromSecondStageToString(secondStage: SecondStage?): String? {
secondStage?.let {
secondStage.apply {
return "$burnTimeSec" +
";" + "$engines" +
";" + "$fuelAmountTons" +
";" + fromPayloadsToString(payloads) +
";" + (if(reusable) "1" else "0") +
";" + fromThrustToString(thrust)
}
}
return null
}
@TypeConverter
fun fromStringToSecondStage(str: String?): SecondStage? {
str?.let {
str.split(";").also {
val payloads = fromStringToPayloads(it[3])
val thrust = fromStringToThrust(it[5])
return if(payloads != null && thrust != null) {
return SecondStage(
burnTimeSec = it[0].toInt(),
engines = it[1].toInt(),
fuelAmountTons = it[2].toDouble(),
payloads = payloads,
reusable = it[4] == "1",
thrust = thrust
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromThrustToString(thrust: Thrust?): String? {
thrust?.let {
return "${thrust.kN};${thrust.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrust(str: String?): Thrust? {
str?.let {
str.split(";").also {
return Thrust(
kN = it[0].toInt(),
lbf = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromPayloadsToString(payloads: Payloads?): String? {
payloads?.let {
return fromCompositeFairingToString(payloads.compositeFairing) + payloads.option1
}
return null
}
@TypeConverter
fun fromStringToPayloads(str: String?): Payloads? {
str?.let {
str.split(";").also {
fromStringToCompositeFairing(it[0])?.let { compositeFairing ->
return Payloads(
compositeFairing = compositeFairing,
option1 = it[1]
)
} ?: return null
}
}
return null
}
@TypeConverter
fun fromCompositeFairingToString(compositeFairing: CompositeFairing?): String? {
compositeFairing?.let {
return fromDiameterToString(compositeFairing.diameter) +
fromHeightToString(compositeFairing.height)
}
return null
}
@TypeConverter
fun fromStringToCompositeFairing(str: String?): CompositeFairing? {
str?.let {
str.split(";").also {
val diameter = fromStringToDiameter(it[0])
val height = fromStringToHeight(it[1])
return if(diameter != null && height != null) {
CompositeFairing(
diameter = diameter,
height = height
)
} else {
null
}
}
}
return null
}
@TypeConverter
fun fromIspToString(isp: Isp?): String? {
isp?.let {
return "${isp.seaLevel};${isp.vacuum}"
}
return null
}
@TypeConverter
fun fromStringToIsp(str: String?): Isp? {
str?.let {
str.split(";").also {
return Isp(
seaLevel = it[0].toInt(),
vacuum = it[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromThrustSeaLevelToString(thrustSeaLevel: ThrustSeaLevel?): String? {
thrustSeaLevel?.let {
return "${thrustSeaLevel.kN};${thrustSeaLevel.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrustSeaLevel(str: String?): ThrustSeaLevel? {
str?.let {
str.split(";").also {
return ThrustSeaLevel(
kN = str[0].toInt(),
lbf = str[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromThrustVacuumToString(thrustVacuum: ThrustVacuum?): String? {
thrustVacuum?.let {
return "${thrustVacuum.kN};${thrustVacuum.lbf}"
}
return null
}
@TypeConverter
fun fromStringToThrustVacuum(str: String?): ThrustVacuum? {
str?.let {
str.split(";").also {
return ThrustVacuum(
kN = str[0].toInt(),
lbf = str[1].toInt()
)
}
}
return null
}
@TypeConverter
fun fromFlickrImagesToString(flickrImages: List<String>?): String? {
flickrImages?.let {
var imagesString = ""
for(image in flickrImages) {
imagesString += "$image;"
}
return imagesString.substring(0, (imagesString.length - 1))
}
return null
}
@TypeConverter
fun fromStringToFlickrImages(str: String?): List<String>? {
str?.let {
return str.split(";")
}
return null
}
@TypeConverter
fun fromPayloadWeightsToString(payloadWeights: List<PayloadWeight>?): String? {
payloadWeights?.let {
var weightsString = ""
for(weight in payloadWeights) {
weightsString += fromPayLoadWeightToString(weight) + ";"
}
return weightsString.substring(0, (weightsString.length - 1))
}
return null
}
@TypeConverter
fun fromStringToPayloadWeights(str: String?): List<PayloadWeight>? {
str?.let {
val weights = mutableListOf<PayloadWeight>()
str.split(";").also {
for(payloadWeight in it) {
fromStringToPayloadWeight(payloadWeight)?.let { payloadWeight ->
weights.add(payloadWeight)
} ?: return null
}
}
return weights
}
return null
}
}
我的方法是有两个模块:launch
和 rocket
。每个都有自己的存储库,每个存储库都构建数据库:
private val dao: Database = Room.databaseBuilder(
context,
Database::class.java,
Database.NAME_DB
).build()
我遇到的问题是出现此错误:java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
。
现在,错误发生是因为 fromStringToIsp()
。这看起来不像是算法错误,因为 Isp
class 只有两个字段,所以我不会在索引上出错。如果我强行通过fromStringToIsp()
,其他一些函数也会报告越界错误。
那么我在实施 TypeConverters
时哪里出错了?
您传递给 fromStringToIsp()
的字符串不包含分号,因为在 fromStringToEngines()
中您正在执行以下操作:
str.split(";").also {
val isp = fromStringToIsp(it[1])
/* ... */
}
然后,在 fromStringToIsp()
中,您执行:
str.split(";").also {
return Isp(
seaLevel = it[0].toInt(),
vacuum = it[1].toInt()
)
}
当试图访问 it[1]
时你会得到一个异常,因为 it
只有一个元素,即 it[0]
.