I have below POC to use Java 8 feature.
I want to update DB after accept method. Is it good to go with andThen()? When is this method called? Who calls it?
What is the basic use of andThen() method? Looking at the docs was confusing.
public class StockTest {
public static void main(String[] args) {
List<Trader> traders = new ArrayList<>();
Random random = new Random();
// Initializing trading a/c's.
for (int i = 0; i < 10; i++) {
Trader trader = new Trader((random.nextInt(100) + 1) * 3);
traders.add(trader);
}
// Display Trade accounts.
System.out.println("Before Bonus, Units are:");
for (Trader trader : traders) {
System.out.print(trader.getUnits() + "\t");
}
// Add bonus to each trader.
traders.forEach(new Consumer<Trader>() {
#Override
public void accept(Trader trader) {
trader.updateBonus(2);
}
#Override
public Consumer<Trader> andThen(Consumer<? super Trader> after)
{
System.out.println("In andThen");
return Consumer.super.andThen(after);
}
});
// Display Trade accounts after bonus applied..
System.out.println("\nAfter bonus:");
for (Trader trader : traders) {
System.out.print(trader.getUnits() + "\t");
}
}
}
class Trader {
private int units;
public Trader(int initialUnits) {
this.units = initialUnits;
}
public int getUnits() {
return units;
}
public void setUnits(int units) {
this.units = units;
}
public void updateBonus(int bonusUnits) {
this.units = this.units * bonusUnits;
}
}
Please help with some example or use cases to utilize this method
In short andThen is used to chain consumers, so the input will go to first and second consumer, lke below:
Consumer<Trader> consumer1 = new Consumer<Trader>() {
#Override
public void accept(Trader trader) {
trader.updateBonus(2);
}
};
Consumer<Trader> consumer2 = new Consumer<Trader>() {
#Override
public void accept(Trader trader) {
// do something
}
};
// Add bonus to each trader.
traders.forEach(consumer1.andThen(consumer2));
So here the Trader will be passed to consumer1, then to consumer2 and so on.
You don't have to implement this method, or override it. When it comes to Consumers, implement only the accept.
andThen method is a helper tool to join consumers. Instead of passing the input to all of them in a loop.
You use andThen when you want to chain the logic of two Consumers. consumer1.andThen(consumer2) first calls the accept method of consumer1 and then calls the accept method of consumer2.
Overriding the default implementation of andThen makes little sense and prevents you from using lambda expressions/method references.
andThen can be used to chain two Consumers:
traders.forEach(((Consumer<Trader>)(trader -> trader.updateBonus(2))).andThen(trader -> System.out.println("some more processing")));
Of course, in this example you can simply put the logic of the two Consumers in a single Consumer:
traders.forEach(trader -> {trader.updateBonus(2);
System.out.println("some more processing");});
It makes more sense to use andThen when you are chaining two existing Consumers:
Consumer<Trader> traderConsumer1 = trader -> trader.updateBonus(2);
Consumer<Trader> traderConsumer2 = trader -> System.out.println(trader);
traders.forEach(traderConsumer1.andThen(traderConsumer2));
Related
In the following code, tick emits a new object every three seconds. I'm trying to count the number of emitted objects every second using groupedWithin (which ignores empty groups). Is there any way in Akka Streams for the following code to print 0 in periods when tick does not emit any objects?
Source.tick(Duration.ZERO, Duration.ofSeconds(3), new Object())
.groupedWithin(Integer.MAX_VALUE, Duration.ofSeconds(1))
.map(List::size)
.runWith(Sink.foreach(e -> System.out.println(e)), materializer);
In other words, I'd like the output of this code to be this sequence: 1 0 0 1 0 0 1 ... (every second) instead of 1 1 1 ... (every three seconds).
EDIT: This is the best workaround I have come up with so far (using keepAlive to send some special objects if the upstream is idle):
Source.tick(Duration.ZERO, Duration.ofSeconds(3), new Object())
.keepAlive(Duration.ofSeconds(1), KeepAliveElement::new)
.groupedWithin(Integer.MAX_VALUE, Duration.ofSeconds(1))
.map(lst -> lst.stream().filter(e -> !(e instanceof KeepAliveElement)).collect(Collectors.toList()))
.map(List::size)
.runWith(Sink.foreach(e -> System.out.println(e)), materializer);
Is there any better way to do this?
I thought this would be of normal difficulty, I was wrong. One thing I wanted to do is to ensure that the flow counting items that pass through the stream does not keep a reference to each item it sees: if many items pass in the aggregation period, you will end up with an unnecessarily big list in memory (even if only for a second) and the performance penalty to add (many) items to it. The following solution, although complex, keeps only a counter.
NOTE: Although I tested the happy scenario, I cannot say this is battle-proven, so use with caution!
Based on Akka's GroupedWeightedWithin and the documentation here:
public class CountInPeriod<T> extends GraphStage<FlowShape<T, Integer>> {
public Inlet<T> in = Inlet.<T>create("CountInPeriod.in");
public Outlet<Integer> out = Outlet.<Integer>create("CountInPeriod.out");
private FlowShape<T, Integer> shape = FlowShape.of(in, out);
private Duration duration;
public CountInPeriod(Duration duration) {
this.duration = duration;
}
#Override
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new TimerGraphStageLogic(shape) {
private int counter = 0;
private int bufferPushCounter = -1;
{
setHandler(in, new AbstractInHandler() {
#Override public void onPush() throws Exception, Exception {
grab(in);
counter++;
pull(in);
}
});
setHandler(out, new AbstractOutHandler() {
#Override public void onPull() throws Exception, Exception {
if (bufferPushCounter >= 0) {
push(out, bufferPushCounter);
bufferPushCounter = -1;
}
}
});
}
#Override
public void preStart() throws Exception, Exception {
scheduleWithFixedDelay(CountInPeriod.class, duration, duration);
pull(in);
}
#Override
public void onTimer(Object timerKey) throws Exception, Exception {
if (isAvailable(out)) emitCounter();
else bufferPush();
}
private void emitCounter() {
push(out, counter);
counter = 0;
bufferPushCounter = -1;
}
private void bufferPush() {
bufferPushCounter = counter;
counter = 0;
}
};
}
#Override
public FlowShape<T, Integer> shape() {
return shape;
}
}
Test code:
public class GroupTicked {
final static ActorSystem as = ActorSystem.create("as");
public static void main(String... args) throws Exception {
CompletionStage<Done> done = Source.tick(Duration.ZERO, Duration.ofSeconds(3), new Object())
.take(7) // to finish in finite time...
.via(new CountInPeriod<>(Duration.ofSeconds(1)))
.runWith(Sink.foreach(e -> System.out.println(System.currentTimeMillis() + " -> " + e)), as);
done.thenAccept(x -> as.terminate());
}
}
I have an existing Java class as follows and I want to monitor number of method invocations for each method in this class using JMX. How do I do it? I tried google but I can't see the big picture on how the whole thing is connected. It would be great if I can see see some code examples
Public class RPCServer {
public void storeSchema() { // want to count number of method invocations
System.out.println("storeSchema");
}
public void getSchema() { // want to count number of method invocations
System.out.println("getSchema");
}
public void storeRow() { // want to count number of method invocations
System.out.println("storeRow");
}
public void getRow() { //want to count number of method invocations
System.out.println("getRow");
}
}
I you want to see how many time some methods are executed through JMX, I propose this solution
First you need an interface for your class. Only the methods of this interface are visible for JMX:
public interface RPCServerInterface {
int countMethodInvocation(String method);
}
Then in the class you store how many time each function is call.
public class RPCServer implements RPCServerInterface{
private int row;
private Map<String,Integer> countByMethod = new HashMap<String,Integer>();
// +1 to the number of time of execution of this method
private void sumMethodInvocation(String method) {
if ( countByMethod.containsKey(method) ) {
int n = countByMethod.get(method);
countByMethod.put(method, n+1);
} else {
countByMethod.put(method,1);
}
}
// how many time the method has been invoked
#Override
public int countMethodInvocation(String method){
return countByMethod.containsKey(method)?countByMethod.get(method):0;
}
public void setRow(int i) {
// register each time is executed
this.sumMethodInvocation("setRow");
this.row = i;
}
public int getRow() {
// register each time is executed
this.sumMethodInvocation("getRow");
return row;
}
}}
}
Then you have to register your Bean:
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
RPCServer rpcServer = new RPCServer();
ObjectName objectName = new ObjectName("org.foo.RPCServer.jmx:type=RPCServerInterface");
StandardMBean standardMBean = new StandardMBean(rpcServer,RPCServerInterface.class);
mBeanServer.registerMBean(standardMBean, objectName);
The path org.foo.RPCServer.jmx is arbitrary.
Then your run jconsole and you find the process you are running.
Then you can run the command countMethodInvocation and you can get the number of execution time.
Like this:
This tutorial can be useful:
what-is-jmx-mbean-jconsole-tutorial
I'm still a relative newbie when it comes to Java, coming mainly from a C# background.
I was discussing the lack of 'out' parameters in Java methods with a colleague and how to work around this. He suggested creating a structure/class to hold the various parameters and passing it back.
Sometimes this feels 'wrong' to me - especially if I have a special method that I want to use to return a subset of parameters from a larger class.
So I wondered about using anonymous inline classes instead to achieve this. Code sample below.
Is this a sensible approach? Just wondering what the perceived wisdom is on this.
public class MyClass {
Patient myPatient = null;
// An interface to enable us to return these variables in a single call
public interface VitalStatsResponse { public void returnStats(int bloodPressure, int heartRate); }
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Lots of other variables here
public void calculateVitalStats(VitalStatsResponse response)
{
response.returnStats((bloodPressure * 2), (heartRate / 10) ;
}
}
public void doWork()
{
// We want the patient's blood pressure and heart rate returned by a single method call, so use an anonymous inline class
myPatient.calculateVitalStats(new VitalStatsResponse() {
#Override
public void returnStats(int bloodPressure, int heartRate) {
// Handle returned variables here
}
});
}
}
I would go for the simple solution of creating a VitalStats object. If you need the VitalStatus of a patient, then VitalStats is a concept in your application that can be represented as an Object.
public class VitalStatus {
final int bloodPressure;
final int heartRate;
public VitalStats(int bloodPressure, int heartRate) {
this.bloodPressure = bloodPressure;
this.heartRate = heartRate;
}
}
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Other variables
public VitalStatus getVitalStatus() {
return new VitalStats(bloodPressured * 2, heartRate / 2);
}
}
Out params is a procedural solution for return times. Java primarily fits the Object Oriented paradigm of programming and as such don't be afraid to make objects. This fits with the S in SOLID if your class is doing a lot of complex things see if you can break it down into smaller more manageable pieces.
I would also use "class to hold the parameters" over "inline anonymous inner class"
public class MyClass implements VitalStatsResponse{
Patient myPatient = null;
private ArrayList<VitalStatsResponse> response;
void MyClass(ArrayList<VitalStatsResponse> response) {
this.response = response;
}
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Lots of other variables here
public void calculateVitalStats()
{
for(int i = 0; i < response.length; i++) {
// call returnStats method of every registered callback
response.get(i).returnStats((bloodPressure * 2), (heartRate / 10) ;
}
}
}
// any client can register/unregister callback via these methods
void registerResponse(VitalStatsResponse response) {
this.response.add(response);
}
void unRegisterResponse(VitalStatsResponse response) {
this.response.remove(response);
}
public void doWork()
{
// We want the patient's blood pressure and heart rate returned by a single method call, so use an anonymous inline class
myPatient.calculateVitalStats();
}
public void returnStats(int bloodPressure, int heartRate) {
// implement the body according to this class requirement
}
}
I have the following task to perform:
I need to emit 2 observables (obs1 & obs2) process their results and then call another observable (obs3) and process its results and if possible that while processing the results of obs3 have access to the results of obs1 and obs2.
This is my draft code which doesn't do the trick, how can I alter it.
public void executeFind(String session_id, long template_id, GameModelType game_model) {
Observable<RxMessage<byte[]>> userObs = context.getUser(session_id);
Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
Observable.zip(userObs, gameObs, new Func2<RxMessage<byte[]>, Game, GameObject>() {
#Override
public GameObject call(RxMessage<byte[]> userRawReply, ActiveGame game) {
..
..
return context.updateGame(game.getGameData())
.subscribe(new Action1<GameObject>() {
#Override
public void call(GameObject updateReply) {
..
..
}
});
return userReply;
}
});
}
This doesn't really work - I can write a code which uses explicit calls to .flatMap\subscribe for each Observable but results in many nested calls which is obviously poor usage of the framework.
What is the right way to solve this??
Thank you!
EDIT:
I've found this solution to work, but I'm still wondering whether there is a "cleaner" way to achieve this:
public void executeFind(ReplyMessage<JsonObject> replyObj, String session_id, long template_id, GameModelType game_model) throws CommandException {
rx.Observable<GameObject> userObs = context.getUser(session_id);
rx.Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
rx.Observable.zip(userObs, gameObs, new Func2<GameObject, Game, List<Object>>() {
#Override
public List<Object> call(GameObject userReply, Game game) {
User user = ...;
final List<Object> results = new ArrayList<Object>(3);
results.add(ErrorCodes.STATUS_OK);
results.add(user);
results.add(game);
context.updateGame(game.getGameData()).subscribe(new Action1<GameObject>() {
#Override
public void call(GameObject updateReply) {
...
}
});
return results;
}
}).subscribe(new Action1<List<Object>>() {
#Override
public void call(List<Object> results) {
int status = (int) results.get(0);
User user = (User) results.get(1);
Game game = (Game) results.get(2);
}
});
}
I would code this thing with the following idea in mind. May be map can be replace with flatMap if that's relevant for your use case. Also note I have only used Java 8 lambdas syntax, but for more readability I strongly advises you to have simple and well named methods (and use them with a method reference) for each of these functions/actions as it will raise understandability of the code (That's what we do on mockito, but everyone should do it in their own code base).
public void executeFind(ReplyMessage<JsonObject> reply_obj, String session_id, long template_id, GameModelType game_model) throws CommandException {
Observable<GameObject> userObs = context.getUser(session_id);
Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
Observable.zip(userObs, gameObs, (userReply, game) -> {
User user = ...;
return GameOfUser.gameFound(game, user);
}).map(gou -> {
context.updateGame(gou.gameData()).susbcribe(...);
return gou;
}).subscribe(gou -> ...);
}
What is the difference between applying the visitor design pattern to your code and the following approach:
interface Dointerface {
public void perform(Object o);
}
public class T {
private Dointerface d;
private String s;
public String getS() {
return s;
}
public T(String s) {
this.s = s;
}
public void setInterface(Dointerface d) {
this.d = d;
}
public void perform() {
d.perform(this);
}
public static void main(String[] args) {
T t = new T("Geonline");
t.setInterface(new Dointerface() {
public void perform(Object o) {
T a = (T)o;
System.out.println(a.getS());
}
});
t.perform();
}
}
I assume that by using interfaces, we're not really separating the algorithm.
There is quite a big difference.
The visitor pattern uses interfaces, but its purpose is to be able to perform an operation to one or more classes (who implement an interface) without having to change the classes. Hence, the implementation actually "visits" the class and does its thing without the class being modified.
An interface is a basic concept used to provide a common API to a potentially diverse group of classes. The typical test for an interface is that classes that share it are alike in at least that one respect (is-like-a) and in those cases can be treated as such.
Here is a simple example on wikipedia that shows a couple of visitors in java.
Two things:
In your example you need two methods. The perfom and the setInterface. With a visitor pattern you would only need one method, the perfom, usually called accept.
If you need more than one 'performer', you will have to set the performer -via the setInterface method- for each. This makes it impossible to make your class immutable.
The most important difference in these examples is that in the visitor case you retain the compile-time concrete type of "this". This allows you to use double dispatch, where the method to be called is dependent on both the concrete data type and the visitor implementation. Double dispatch is just a special case of multiple dispatch where the method invoked is dependent on the receiver and the types of the parameters to the method. Java is of course single dispatch but some other languages support multiple dispatch.
The basic driving force behind the visitor pattern is that by using interfaces on the concrete nodes, every operation that needs to be added to a composite data structure must change every node. The visitor pattern uses a generic (static) pattern on the nodes so that dynamically adding operations is easy. The downside is that modifying the data structure (by adding or removing concrete nodes) becomes more difficult as all operation visitors are affected.
In general, this trade=off is a better match as it's more frequent to extend operations over a data structure than to change the data structure itself. Here's a lengthier writing of mine on how to use visitors and a bunch of considerations:
http://tech.puredanger.com/2007/07/16/visitor/
You might fairly ask if there is a pattern that allows us to do both: add operations or extend our data structures without breaking existing code. This is known as The Expression Problem as coined by Philip Wadler. You can find some links on this and more here:
http://tech.puredanger.com/presentations/design-patterns-reconsidered
A Visitor pattern is used when you have a data structure made up of many different classes and you have multiple algorithms that require a different operation for each class. In your example your DoInterface implementation only does one operation on one type. The only thing you do is print the result of getS() and because you cast o to T you can only do this to classes of type T.
If you wanted to apply your interface to a typical visitor style class you your the class with your DoInterface.perform function would likely end up with a big if else if statement in it something like this:
public void visit(Object o) {
if (o instanceof File)
visitFile((File)o);
else if (o instanceof Directory)
visitDirectory((Directory)o);
else if (o instanceof X)
// ...
}
Because this uses Object it will allow callers with any type which can create errors which will only show up at runtime. A Visitor gets around this by creating a “visitType” function for each type in the data structure. The classes in the data structure are then responsible for knowing which function on the visitor to call. The mapping is performed by each of the data structure’s classes implementing an accept function that then calls back on the Visitor class. If the function for the type does not exist on the visitor you get a compile error. The accept method looks like this:
#Override
public void accept(FileSystemVisitor v) {
v.visitFile(this);
}
Part of the trouble with the Visitor pattern is that it takes quite a lot of code to really do it justice in a sample. I think this is why a lot of people don't get it as it is easy to get distracted by the other code. I have created a simple file system sample that hopefully shows how to use a visitor more clearly. It creates a composite with some files and directories in and then performs two operations on the hierarchy. In practice you would probably want more than two data classes and two operations to justify this pattern but this is only an example.
public class VisitorSample {
//
public abstract class FileSystemItem {
public abstract String getName();
public abstract int getSize();
public abstract void accept(FileSystemVisitor v);
}
//
public abstract class FileSystemItemContainer extends FileSystemItem {
protected java.util.ArrayList<FileSystemItem> _list = new java.util.ArrayList<FileSystemItem>();
//
public void addItem(FileSystemItem item)
{
_list.add(item);
}
//
public FileSystemItem getItem(int i)
{
return _list.get(i);
}
//
public int getCount() {
return _list.size();
}
//
public abstract void accept(FileSystemVisitor v);
public abstract String getName();
public abstract int getSize();
}
//
public class File extends FileSystemItem {
//
public String _name;
public int _size;
//
public File(String name, int size) {
_name = name;
_size = size;
}
//
#Override
public void accept(FileSystemVisitor v) {
v.visitFile(this);
}
//
#Override
public String getName() {
return _name;
}
//
#Override
public int getSize() {
return _size;
}
}
//
public class Directory extends FileSystemItemContainer {
//
private String _name;
//
public Directory(String name) {
_name = name;
}
//
#Override
public void accept(FileSystemVisitor v) {
v.visitDirectory(this);
}
//
#Override
public String getName() {
return _name;
}
//
#Override
public int getSize() {
int size = 0;
for (int i = 0; i < _list.size(); i++)
{
size += _list.get(i).getSize();
}
return size;
}
}
//
public abstract class FileSystemVisitor {
//
public void visitFile(File f) { }
public void visitDirectory(Directory d) { }
//
public void vistChildren(FileSystemItemContainer c) {
for (int i = 0; i < c.getCount(); i++)
{
c.getItem(i).accept(this);
}
}
}
//
public class ListingVisitor extends FileSystemVisitor {
//
private int _indent = 0;
//
#Override
public void visitFile(File f) {
for (int i = 0; i < _indent; i++)
System.out.print(" ");
System.out.print("~");
System.out.print(f.getName());
System.out.print(":");
System.out.println(f.getSize());
}
//
#Override
public void visitDirectory(Directory d) {
for (int i = 0; i < _indent; i++)
System.out.print(" ");
System.out.print("\\");
System.out.print(d.getName());
System.out.println("\\");
//
_indent += 3;
vistChildren(d);
_indent -= 3;
}
}
//
public class XmlVisitor extends FileSystemVisitor {
//
private int _indent = 0;
//
#Override
public void visitFile(File f) {
for (int i = 0; i < _indent; i++)
System.out.print(" ");
System.out.print("<file name=\"");
System.out.print(f.getName());
System.out.print("\" size=\"");
System.out.print(f.getSize());
System.out.println("\" />");
}
//
#Override
public void visitDirectory(Directory d) {
for (int i = 0; i < _indent; i++)
System.out.print(" ");
System.out.print("<directory name=\"");
System.out.print(d.getName());
System.out.print("\" size=\"");
System.out.print(d.getSize());
System.out.println("\">");
//
_indent += 4;
vistChildren(d);
_indent -= 4;
//
for (int i = 0; i < _indent; i++)
System.out.print(" ");
System.out.println("</directory>");
}
}
//
public static void main(String[] args) {
VisitorSample s = new VisitorSample();
//
Directory root = s.new Directory("root");
root.addItem(s.new File("FileA", 163));
root.addItem(s.new File("FileB", 760));
Directory sub = s.new Directory("sub");
root.addItem(sub);
sub.addItem(s.new File("FileC", 401));
sub.addItem(s.new File("FileD", 543));
Directory subB = s.new Directory("subB");
root.addItem(subB);
subB.addItem(s.new File("FileE", 928));
subB.addItem(s.new File("FileF", 238));
//
XmlVisitor xmlVisitor = s.new XmlVisitor();
root.accept(xmlVisitor);
//
ListingVisitor listing = s.new ListingVisitor();
root.accept(listing);
}
}
The only thing that I see that is readily obvious is that by storing the interface, you make it so you have to do two operations rather than one to invoke it. I suppose that this could make sense if you are repeatedly going to perform the same action once the interface is set, but I think you could stick with the standard Visitor and accomplish the same thing.