Why Kotlin doesn't implement Int.plus(value: String)? - syntax

It causes discomfort when you can do that:
val string = " abc "
val integer = 8
val result = string + integer
and can't do:
val result = integer + string
It has hidden meaning or it's an omission?

Kotlin is static typed language and in basicly you can't add String to Integer. But there are possible to overload operators, so we can now.
In case when we want add any object to string, it's clear: every object can be implicitly converted to String (Any#toString())
But in case of Int + smthg it's not so clear, so only Int + kotlin.Number is defined in standard library.
I suggest to use string interpolation:
val result = "${integer}${string}"
Or define own overloaded plus operator:
operator fun Int.plus(string: String): String = string + this

Related

Parse log entries with least possible overhead

I have some log format with entries like this:
log_entry_no1 := "2021-11-03 7:7:51 hal9000 evil_app heartbeat C99 I am sorry Dave"
Those "fields" are separated by space except the last one called message which is just log data and can contain spaces.
My question is. Is there better way to process those entries without first splitting whole sentence and then join'ing that last part (message) with less overhead using go?
type LogData struct {
d Date // yyyy-mm-dd Mandatory
t Time // hh:mm:ss Mandatory
hostname string // Mandatory
app_id string // Mandatory
etype string // enum based string Mandatory
level string // Optional base on etype
message string // Mandatory
}
log_fields := strings.Split(log_entry_no1, " ")
var log_data = LogData{}
log_data.d = parseTime(log_entry_no1[0])
log_data.t = parseTime(log_entry_no1[1])
//...
if log_fields[4] == "heartbeat" {
log_data.level = log_fields[5]
log_data.message = strings.Join(log_fields[6:], " ")
} else {
log_data.message = strings.Join(log_fields[5:], " ")
}
Use strings.SplitN.
func SplitN(s, sep string, n int) []string
The docs say if n is greater than zero: it returns at most n substrings; the last substring will be the unsplit remainder.

how to decode an hexacidemal values to decimal ones with springboot?

i don't know how to decode hexacidemal values to decimal ones with springboot
Is There a default fonctions That can help me or should i develop functions by myself
thank You
You just need JAVA APIs,
From Hexadecimal to Decimal
String hexNumber = ...
int decimal = Integer.parseInt(hexNumber, 16);
System.out.println("Hex value is " + decimal);
From Decimal to Hex
If you have the value that you want to convert in an int variable, then you can simply call:
int i = ...
String hex = Integer.toHexString(i);
System.out.println("Hex value is " + hex);
If you have the decimal number in a String, then you first call Integer.parseInt() but this time you don't need any second parameter— decimal is the default:
String string = ...
int no = Integer.parseInt(string);
String hex = Integer.toHexString(no);
System.out.println("Hex value is " + hex);
Check out the full paper here.

Efficient Sequence conversion to String

I have a string sequence Seq[String] which represents stdin input lines.
Those lines map to a model entity, but it is not guaranteed that 1 line = 1 entity instance.
Each entity is delimited with a special string that will not occur anywhere else in the input.
My solution was something like:
val entities = lines.mkString.split(myDelimiter).map(parseEntity)
parseEntity implementation is not relevant, it gets a String and maps to a case class which represents the model entity
The problem is with a given input, I get an OutOfMemoryException on the lines.mkString. Would a fold/foldLeft/foldRight be more efficient? Or do you have any better alternative?
You can solve this using akka streams and delimiter framing. See this section of the documentation for the basic approach.
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Framing, Source}
import akka.util.ByteString
val example = (0 until 100).mkString("delimiter").grouped(8).toIndexedSeq
val framing = Framing.delimiter(ByteString("delimiter"), 1000)
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
Source(example)
.map(ByteString.apply)
.via(framing)
.map(_.utf8String)
.runForeach(println)
The conversion to and from ByteString is a bit annoying, but Framing.delimiter is only defined for ByteString.
If you are fine with a more pure functional approach, fs2 will also offer primitives to solve this problem.
Something that worked for me if you are reading from a stream (your mileage may vary). Slightly modified version of Scala LineIterator:
class EntityIterator(val iter: BufferedIterator[Char]) extends AbstractIterator[String] with Iterator[String] {
private[this] val sb = new StringBuilder
def getc() = iter.hasNext && {
val ch = iter.next
if (ch == '\n') false // Replace with your delimiter here
else {
sb append ch
true
}
}
def hasNext = iter.hasNext
def next = {
sb.clear
while (getc()) { }
sb.toString
}
}
val entities =
new EnityIterator(scala.io.Source.fromInputStream(...).iter.buffered)
entities.map(...)

Groovy MissingMethodException when working with UTF-8

Currently I have the following String:
String str = "Hello my name\n\t\t\t\tis Earl."
The problem is that the remote process that handles this String doesn't like the character encoding of the newline and tab characters. This remote process expects UTF-8.
So I wrote convertSpecCharsToUtf8() method:
private String convertSpecCharsToUtf8() {
// "\n\t\t\t\t" as UTF-8
char[] utf8 = new char[6]
char[0] = '\\u000D'
char[1] = '\\u000A'
char[2] = char[3] = char[4] = char[5] = '\\u0009'
new String(utf8)
}
And then changed my str String to:
String str = "Hello my name" + convertSpecCharsToUtf8() + "is Earl."
When I run:
println "Testing UTF8"
String str = "Hello my name" + utf8CRLFTabFormat() + "is Earl."
println str
I get:
Testing UTF8
Caught: groovy.lang.MissingMethodException: No signature of method: static char.putAt() is applicable for argument types: (java.lang.Integer, java.lang.String) values: [0, \u000D]
groovy.lang.MissingMethodException: No signature of method: static char.putAt() is applicable for argument types: (java.lang.Integer, java.lang.String) values: [0, \u000D]
at com.me.myapp.convertSpecCharsToUtf8(Widget.groovy:133)
at com.me.myapp.execute(Widget.groovy:111)
at com.me.myapp$execute.call(Unknown Source)
at com.me.myapp.main(Widget.groovy:37)
Why, and what's the solution here?
There's a typo. Should be:
private String convertSpecCharsToUtf8() {
// "\n\t\t\t\t" as UTF-8
char[] utf8 = new char[6]
utf8[0] = '\\u000D'.toCharacter()
utf8[1] = '\\u000A'.toCharacter()
utf8[2] = utf8[3] = utf8[4] = utf8[5] = '\\u0009'.toCharacter()
new String(utf8)
}
You can write a list with each character and use the as operator to coerce to char[]. You may also use /str/ string declaration to avoid double escaping the backslash:
String convertSpecCharsToUtf8() {
new String( [/\u000D/, /\u000A/] + [/\u0009/] * 4 as char[] )
}
def str = "Hello my name" + convertSpecCharsToUtf8() + "is Earl."
assert str == """Hello my name
is Earl."""

Slow Scala assert

We've been profiling our code recently and we've come across a few annoying hotspots. They're in the form
assert(a == b, a + " is not equal to " + b)
Because some of these asserts can be in code called a huge amount of times the string concat starts to add up. assert is defined as:
def assert(assumption : Boolean, message : Any) = ....
why isn't it defined as:
def assert(assumption : Boolean, message : => Any) = ....
That way it would evaluate lazily. Given that it's not defined that way is there an inline way of calling assert with a message param that is evaluated lazily?
Thanks
Lazy evaluation has also some overhead for the function object created. If your message object is already fully constructed (a static message) this overhead is unnecessary.
The appropriate method for your use case would be sprintf-style:
assert(a == b, "%s is not equal to %s", a, b)
As long as there is a speciaized function
assert(Boolean, String, Any, Any)
this implementation has no overhead or the cost of the var args array
assert(Boolean, String, Any*)
for the general case.
Implementing toString would be evaluated lazily, but is not readable:
assert(a == b, new { override def toString = a + " is not equal to " + b })
It is by-name, I changed it over a year ago.
http://www.scala-lang.org/node/825
Current Predef:
#elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
if (!assertion)
throw new java.lang.AssertionError("assertion failed: "+ message)
}
Thomas' answer is great, but just in case you like the idea of the last answer but dislike the unreadability, you can get around it:
object LazyS {
def apply(f: => String): AnyRef = new {
override def toString = f
}
}
Example:
object KnightSpeak {
override def toString = { println("Turned into a string") ; "Ni" }
}
scala> assert(true != false , LazyS("I say " + KnightSpeak))
scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni
Try: assert( a==b, "%s is not equals to %s".format(a,b))
The format should only be called when the assert needs the string. Format is added to RichString via implicit.

Resources