Sie sind auf Seite 1von 16

Creating Custom Java Functions

Contents
Custom Java Function Samples
Creating Custom Java Simple Functions
Creating Custom Java Aggregate Functions
Method Parameter and Return Types
Related Topics
You can call custom Java functions directly in StreamBase expressions by an alias defined in the server
configuration file, or by using the calljava() function. The StreamBase expression language provides
two forms of thecalljava() function, to be used in StreamBase simple and aggregate expressions.
This topic provides guidelines for creating StreamBase custom functions in Java.
Note

StreamBase Studio ships with new projects configured by default to build with Java 6. As of
release 7.4, Java 5 is no longer supported within Studio or for developing Custom Extensions,
including Java functions.

Custom Java Function Samples


The StreamBase installation includes the source files for two custom Java function samples:
Sample

Described in

custom-java-function

Custom Java Simple Function Sample

custom-java-aggregate

Custom Java Aggregate Function Sample

Custom aggregate functions are built by extending


the com.streambase.sb.operator.AggregateWindow class of the StreamBase Java Client library.
This class is described in Java API Documentation.

Creating Custom Java Simple Functions


Simple custom Java functions can be called in expressions in the context of most StreamBase
components, other than the Aggregate operator. Follow these steps to create a custom Java simple
function:

Use the New StreamBase Java Function wizard to create the base code, as described in Using
the StreamBase Java Function Wizard.
Implement a public static in a public Java class.
Observe the guidelines in Method Parameter and Return Types.

For example, Hypotenuse.java in the sample application declares the following class and method:
public class Hypotenuse {
public static double calculate(double a, double b) {
return Math.sqrt(a*a + b*b);
}
}
At compile time, the calljava() implementation looks for only a single method matching the exact
types of the function call in the StreamBase expression. But there can be multiple matching methods,
such as these two functionally equivalent ones:

public static boolean isZero(int i) { return i == 0; }


public static Boolean isZero(Integer i) {
return i == null ? null : Boolean.valueOf(i.intValue() == 0);
}
If this case occurs, StreamBase throws an error.

Creating Custom Java Aggregate Functions


Follow these steps to create a custom Java aggregate function:

Use the New StreamBase Java Function wizard to create the base code, as described in Using
the StreamBase Java Function Wizard.
Define a Java class that extends
the com.streambase.sb.operator.AggregateWindow class.

Observe the guidelines in Method Parameter and Return Types.


Observe the guidelines in the annotations to the example below.

Consider the following annotated example:


package com.mycompany;
import com.streambase.sb.operator.AggregateWindow;
public class MyStdev extends AggregateWindow {
private double sum;
private double sumOfSquares;
private int count;
public void init() {

sum = sumOfSquares = 0.0;


count = 0;

public double calculate() {


return Math.sqrt((count * sumOfSquares - sum*sum) / count*(count-1));
}
public void accumulate(double value) {

sum += value;
sumOfSquares += value*value;
++count;

public void release() { /* nothing to release in this example */ }


}
The following annotations describe points of interest in the preceding example:
Declare a public class that extends the AggregateWindow class (as documented in the
StreamBase Java Client library).
The init() method is called at the start of each new use of the class. Since custom aggregate
objects are likely to be reused, perform all initialization in init() rather than in the
constructor. (The constructor is called only once, while init() is called before each use.)
Your implementation must contain a calculate() method that takes no arguments and returns

a value that is convertible to a StreamBase data type. The calculate() method may be called
several times, or not at all.
Your implementation must provide at least one accumulate() method, and can optionally
provide several overloaded accumulate() methods, one per data
type. calljava() determines which one to call based on type. The argument types
for accumulate() and the return type for calculate() can be any of the types described in
the table in the next section.
The release() method is called at the end of each use of the class.

Method Parameter and Return Types


The method can have any number of parameters, including none. Each parameter must be a Java
primitive or object type corresponding to a StreamBase data type as shown in the following table:
StreamBase Data Type

Java Primitive

Java Object

blob

com.streambase.sb.ByteArrayView

bool

boolean

java.lang.Boolean

double

double

java.lang.Double

int

int

java.lang.Integer

long

long

java.lang.Long

list

primitive_type[]

java.util.List

string

byte[]

java.lang.String

timestamp

com.streambase.sb.Timestamp

tuple

com.streambase.sb.Tuple

Notes

For simple functions, the return type cannot be void, and must be one of the Java primitive or
Java Object types shown above.
You can use java.lang.String anywhere a byte[] is acceptable as an argument or return
value. In this case, the StreamBase string is transparently converted to or from
a java.lang.String using the system default encoding.
If a parameter's type is byte[] and its value is null, it is represented as a Java null. Likewise,
if a Java method with a byte[] return type returns a null, the calling StreamBase expression will
see the return value as string(null).
You can pass a list of lists to functions expecting multi-dimensional array arguments. You can
mix list and array notations when doing this. That is, a two-dimensional list of doubles can be
passed to functions accepting any of the following arguments:
o
double[][]
o
list<double[]>
o
list<list<double>>
Note

Only Java primitive arrays and string arrays are compatible with lists, not complex data types
such as timestamps or tuples. Data type coercion is not supported.
Note

When an array argument has more than two dimensions, you cannot use a function alias. You
must invoke the function via calljava().

For better performance, Java functions can return arrays in place of lists. For example, the
following return types are equivalent:
double[]

foo() {}

// ==

list(double)

double[][][] foo() {}

// == list(list(list(double)))

If the parameter or return type is list or tuple, you must either provide a custom function
resolver, or must define the argument types in a custom-function element in the server
configuration file. See Custom Functions with Complex Data Types for details.
If any value of a parameter with a primitive type is null at runtime, the method that
implements the custom function is not invoked. However, Java Object parameter types can be used
to pass in null parameter values.
For example, if a StreamBase custom function call would involve converting a
StreamBase int(null) or bool(null) value to a primitive Java int or boolean, the method is
not called, and null is assumed as the return value.
public static boolean isZero(int i) { return i == 0; }
calljava("TheClass", "isZero", 1)
calljava("TheClass", "isZero", 0)
calljava("TheClass", "isZero", int(null))

Related Topics

Simple calljava() function


Aggregate calljava() function
Java API Documentation
Class AggregateWindow
StreamBase Custom Java Function Sample
StreamBase Custom Java Aggregate Sample

Creating Method:
Considering the following example to explain the syntax of a method:
public static int funcName(int a, int b) {
// body
}
Here,

public static : modifier.

int: return type

funcName: function name

a, b: formal parameters

int a, int b: list of parameters


Methods are also known as Procedures or Functions:

Procedures: They don't return any value.

/* false *
/* true */
/* null */

Functions: They return value.

Method definition consists of a method header and a method body. The same is shown below:
modifier returnType nameOfMethod (Parameter List) {
// method body
}
The syntax shown above includes:

modifier: It defines the access type of the method and it is optional to use.

returnType: Method may return a value.


nameOfMethod: This is the method name. The method signature consists of the method name and the

parameter list.
Parameter List: The list of parameters, it is the type, order, and number of parameters of a method. These

are optional, method may contain zero parameters.


method body: The method body defines what the method does with statements.

Example:
Here is the source code of the above defined method called max(). This method takes two parameters num1 and
num2 and returns the maximum between the two:
/** the snippet returns the minimum between two numbers */
public static int minFunction(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}

Method Calling:
For using a method, it should be called. There are two ways in which a method is called i.e. method returns a value or
returning nothing (no return value).
The process of method calling is simple. When a program invokes a method, the program control gets transferred to
the called method. This called method then returns control to the caller in two conditions, when:

return statement is executed.

reaches the method ending closing brace.

The methods returning void is considered as call to a statement. Lets consider an example:
System.out.println("This is tutorialspoint.com!");
The method returning value can be understood by the following example:
int result = sum(6, 9);

Example:
Following is the example to demonstrate how to define a method and how to call it:
public class ExampleMinNumber{

public static void main(String[] args) {


int a = 11;
int b = 6;
int c = minFunction(a, b);
System.out.println("Minimum Value = " + c);
}

/** returns the minimum of two numbers */


public static int minFunction(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}
}
This would produce the following result:
Minimum value = 6

The void Keyword:


The void keyword allows us to create methods which do not return a value. Here, in the following example we're
considering a void method methodRankPoints. This method is a void method which does not return any value. Call to
a void method must be a statement i.e. methodRankPoints(255.7);. It is a Java statement which ends with a
semicolon as shown below.

Example:

public class ExampleVoid {

public static void main(String[] args) {


methodRankPoints(255.7);
}

public static void methodRankPoints(double points) {


if (points >= 202.5) {
System.out.println("Rank:A1");
}
else if (points >= 122.4) {
System.out.println("Rank:A2");
}
else {
System.out.println("Rank:A3");
}
}
}
This would produce the following result:
Rank:A1

Passing Parameters by Value:


While working under calling process, arguments is to be passed. These should be in the same order as their
respective parameters in the method specification. Parameters can be passed by value or by reference.
Passing Parameters by Value means calling a method with a parameter. Through this the argument value is passed to
the parameter.

Example:
The following program shows an example of passing parameter by value. The values of the arguments remains the
same even after the method invocation.
public class swappingExample {

public static void main(String[] args) {


int a = 30;
int b = 45;

System.out.println("Before swapping, a = " +


a + " and b = " + b);

// Invoke the swap method

swapFunction(a, b);
System.out.println("\n**Now, Before and After swapping values will be same
here**:");
System.out.println("After swapping, a = " +
a + " and b is " + b);
}

public static void swapFunction(int a, int b) {

System.out.println("Before swapping(Inside), a = " + a


+ " b = " + b);
// Swap n1 with n2
int c = a;
a = b;
b = c;

System.out.println("After swapping(Inside), a = " + a


+ " b = " + b);
}
}
This would produce the following result:
Before swapping, a = 30 and b = 45
Before swapping(Inside), a = 30 b = 45
After swapping(Inside), a = 45 b = 30
**Now, Before and After swapping values will be same here**:
After swapping, a = 30 and b is 45

Method Overloading:
When a class has two or more methods by same name but different parameters, it is known as method overloading. It
is different from overriding. In overriding a method has same method name, type, number of parameters etc.
Lets consider the example shown before for finding minimum numbers of integer type. If, lets say we want to find
minimum number of double type. Then the concept of Overloading will be introduced to create two or more methods
with the same name but different parameters.
The below example explains the same:
public class ExampleOverloading{

public static void main(String[] args) {


int a = 11;
int b = 6;
double c = 7.3;
double d = 9.4;

int result1 = minFunction(a, b);


// same function name with different parameters
double result2 = minFunction(c, d);
System.out.println("Minimum Value = " + result1);
System.out.println("Minimum Value = " + result2);
}

// for integer
public static int minFunction(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}
// for double
public static double minFunction(double n1, double n2) {
double min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}
}
This would produce the following result:
Minimum Value = 6
Minimum Value = 7.3
Overloading methods makes program readable. Here, two methods are given same name but with different
parameters. The minimum number from integer and double types is the result.

Using Command-Line Arguments:


Sometimes you will want to pass information into a program when you run it. This is accomplished by passing
command-line arguments to main( ).
A command-line argument is the information that directly follows the program's name on the command line when it is
executed. To access the command-line arguments inside a Java program is quite easy.they are stored as strings in
the String array passed to main( ).

Example:
The following program displays all of the command-line arguments that it is called with:
public class CommandLine {

public static void main(String args[]){


for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " +
args[i]);
}
}
}
Try executing this program as shown here:
java CommandLine this is a command line 200 -100
This would produce the following result:
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

The Constructors:
A constructor initializes an object when it is created. It has the same name as its class and is syntactically similar to a
method. However, constructors have no explicit return type.
Typically, you will use a constructor to give initial values to the instance variables defined by the class, or to perform
any other startup procedures required to create a fully formed object.
All classes have constructors, whether you define one or not, because Java automatically provides a default
constructor that initializes all member variables to zero. However, once you define your own constructor, the default
constructor is no longer used.

Example:
Here is a simple example that uses a constructor:
// A simple constructor.
class MyClass {
int x;

// Following is the constructor


MyClass() {
x = 10;
}
}
You would call constructor to initialize objects as follows:
public class ConsDemo {

public static void main(String args[]) {


MyClass t1 = new MyClass();
MyClass t2 = new MyClass();
System.out.println(t1.x + " " + t2.x);
}
}
Most often, you will need a constructor that accepts one or more parameters. Parameters are added to a constructor
in the same way that they are added to a method, just declare them inside the parentheses after the constructor's
name.

Example:
Here is a simple example that uses a constructor:
// A simple constructor.
class MyClass {
int x;

// Following is the constructor


MyClass(int i ) {
x = i;
}
}
You would call constructor to initialize objects as follows:
public class ConsDemo {

public static void main(String args[]) {


MyClass t1 = new MyClass( 10 );
MyClass t2 = new MyClass( 20 );
System.out.println(t1.x + " " + t2.x);
}
}

This would produce the following result:


10 20

Variable Arguments(var-args):
JDK 1.5 enables you to pass a variable number of arguments of the same type to a method. The parameter in the
method is declared as follows:
typeName... parameterName
In the method declaration, you specify the type followed by an ellipsis (...) Only one variable-length parameter may be
specified in a method, and this parameter must be the last parameter. Any regular parameters must precede it.

Example:
public class VarargsDemo {

public static void main(String args[]) {


// Call method with variable args
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3});
}

public static void printMax( double... numbers) {


if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}

double result = numbers[0];

for (int i = 1; i <


if (numbers[i] >

numbers.length; i++)
result)

result = numbers[i];
System.out.println("The max value is " + result);
}
}
This would produce the following result:
The max value is 56.5
The max value is 3.0

The finalize( ) Method:

It is possible to define a method that will be called just before an object's final destruction by the garbage collector.
This method is called finalize( ), and it can be used to ensure that an object terminates cleanly.
For example, you might use finalize( ) to make sure that an open file owned by that object is closed.
To add a finalizer to a class, you simply define the finalize( ) method. The Java runtime calls that method whenever it
is about to recycle an object of that class.
Inside the finalize( ) method, you will specify those actions that must be performed before an object is destroyed.
The finalize( ) method has this general form:
protected void finalize( )
{
// finalization code here
}
Here, the keyword protected is a specifier that prevents access to finalize( ) by code defined outside its class.
This means that you cannot know when or even if finalize( ) will be executed. For example, if your program ends
before garbage collection occurs, finalize( ) will not execute.

Method Headers
We summarize method headers, define the signature of a
method, and discuss its use. This material is covered in
more detail in the course text, Gries/Gries.
A method declaration consists of a specification (as a
comment), a method header, and a body. Here is a method
declaration:
/** = "x is in the range 1..50". */
public boolean isLess(int x) {
return x >= 1 && x <= 50;
}

Here is the format of the method header we use in this


class for the three kinds of methods in Java, giving
information about calls on each kind of method, with a few
notes below:

Kind of
method

Format of header

A call on a method:

procedure

public void <name>

Is a statement.

( <parameter-list> ) ;

function

public <return-type> <name>

Is an expression, which yields a value.

( <parameter-list> )

constructo

public <class-name>

Appears in a new-expression or as the first

( <parameter-list> )

statement of a constructor.

Notes

Keyword public may be replaced by private,


if you want the method to be accessible only in the class in
which it is declared.
The <name> is any Java identifier. Conventions for it
are covered below.
The <return-type> is the <type> of the value
returned by the function. It could be a primitive type or a
class type.
The <parameter-list> contains declarations of the
parameters of the method. It is a (possibly empty)
sequence of declarations separated by commas. Each
declaration has the form <type> <variable-name>.
The <class-name> is the name of the class in which
the constructor is declared.
If the class in which this method header appears is

abstract may appear after


the access modifier (public or private). This is
abstract, then keyword

explained in another section.

For a function or procedure, place

keyword static after the access modifier if the method


does not refer directly to an instance variable or instance
method of the class. Then, there will be only one copy of
the method, and it will be placed in the file-drawer of the
class.

Method names
A method name is often written as a sequence of one or
more words, like toString, setName,
andisLess. The first letter of each word, except the
first, is capitalized.
A procedure name is usually a command to do something,
e.g. setName, printArea, fixName.
A function name is usually one of:

a noun phrase that describes the value returned,


e.g.

sin, sqrt, smallestName;


the name of an algorithm,

quicksort, selectionSort, binary


Search;
e.g.

for a boolean function, a true-false phrase that


indicates its value, e.g.

isLess, areRed;

for a getter method, the name of a field preceded


by

get, e.g. getTitle.

Method signature
The signature of a method consists of its name and the
types of its parameters (enclosed in parentheses and
separated by commas). For example, the signature of the
method declared near the beginning of this webpage is
isLess(int)

In Java, the methods in a class must have different


signatures. This means, for example, that one cannot have
both a procedure and a function with name

isLess and

one int parameter. Java constrains methods in this


fashion so that, for any method call, there is no ambiguity
concerning which method is being called.

Das könnte Ihnen auch gefallen