Casting
This guide covers casting in Deephaven. Data type conversion, or casting for short, is the process of changing a value from one data type to another.
In tables, casting is essential to ensure that columns are in the correct format for subsequent operations. It's also vital for optimizing performance and managing memory effectively.
Type casts
A type cast is an expression that converts a value from one data type to another:
a = 3
b = (double) a
In Deephaven, type casts in query strings ensure that columns convert the data type of a column to another.
Groovy variables
The following query creates a column using a Groovy variable. The column is automatically inferred as a BigDecimal
type. A type cast is used to convert the variable to a Java primitive double
:
a = 1.24
source = emptyTable(1).update(
"IntegerA = a",
"IntA = (double)a",
)
sourceMeta = source.meta()
Type casting Groovy variables in query strings has limitations. Unlike Groovy, where numeric types can be automatically promoted, Java primitives have fixed precision. You cannot cast a value to a type with smaller precision without potential data loss. For example, the following query may lose precision:
a = 3.14159
source = emptyTable(1).update(
"DoubleA = a",
"FloatA = (float)a",
)
sourceMeta = source.meta()
The Groovy BigDecimal
type (default for decimal literals) corresponds most closely to the Java double
type in terms of precision. When a Groovy decimal is used in a query string, explicit casting ensures the correct Java primitive type is used.
Groovy closures
Groovy closures called in query strings should generally use explicit parameter and return type declarations rather than relying solely on type casts. However, type casts can still be used when needed to ensure the correct column data type.
The following example uses a type cast to convert the returned value of a Groovy closure to a java.lang.String
:
Note
The shorthand notation (String)
is used below. The full notation is (java.lang.String)
.
randomSymbol = {
def symbols = ["AAPL", "GOOG", "MSFT"]
return symbols[new Random().nextInt(symbols.size())]
}
source = emptyTable(10).update("Symbol = (String)randomSymbol()")
Groovy classes
Groovy classes used in query strings benefit from explicit type casts to ensure columns have the appropriate data types. The example below demonstrates using type casts with Groovy class methods and attributes in query strings:
class MyClass {
static int myValue = 3
public int x
public int y
MyClass(int x, int y) {
this.x = x
this.y = y
}
static int changeValue(int newValue) {
MyClass.myValue = newValue
return newValue
}
static double multiplyModulo(int x, int y, int modulo) {
if (modulo == 0) {
return x * y
}
return (x % modulo) * (y % modulo)
}
int plusModulo(int modulo) {
if (modulo == 0) {
return this.x + this.y
}
return (this.x % modulo) + (this.y % modulo)
}
}
// Make the class available in the query scope
getBinding().setVariable("MyClass", MyClass)
myClass = new MyClass(15, 6)
// Access static variable directly, not through class
value1 = MyClass.changeValue(4)
value2 = MyClass.changeValue(5)
source = emptyTable(1).update(
"Q = value1",
"X = value2",
"Y = (double)myClass.multiplyModulo(11, 16, X)",
"Z = (int)myClass.plusModulo(X)",
)
sourceMeta = source.meta()
Common casting scenarios
Numeric conversions
When working with numeric data, explicit casting ensures the correct Java primitive type:
source = emptyTable(1).update(
"ByteVal = (byte)127",
"ShortVal = (short)32767",
"IntVal = (int)2147483647",
"LongVal = (long)9223372036854775807L",
"FloatVal = (float)3.14f",
"DoubleVal = (double)3.14159265359",
)
sourceMeta = source.meta()
String conversions
Converting between strings and other types:
source = emptyTable(1).update(
"StringNum = `123`",
"IntFromString = (int)parseInt(StringNum)",
"IntToString = (String)Integer.toString(456)",
)
sourceMeta = source.meta()