I need to write the method which let to store always last 10 (the newset) elements and only 10.I have tried to use CircularFifoBuffer.It works perfectly usee like this:
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import org.apache.commons.collections4.queue.CircularFifoQueue;
public class Main {
public static void main(String[] args) {
Queue<Integer> fifo = new CircularFifoQueue<Integer>(3);
fifo.add(11);
fifo.add(22);
fifo.add(33);
fifo.add(44);
fifo.add(55);
System.out.println(fifo); // [33, 44, 55]
But it doesn;t work when used inside the method:
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import org.apache.commons.collections4.queue.CircularFifoQueue;
public class TV {
public int channelNumber = 11;
public int getChannelNumber() {
return channelNumber;
}
public void addToChannelsHistory(int channnelNumber) {
Queue<Integer> fifo = new CircularFifoQueue<Integer>(3);
fifo.add(channnelNumber);
System.out.print(fifo);
}
}
Could you help what to use instead?
You have to use the notion of attribute, a member of your class which is a data, not a method:
public class TV {
private final Queue<Integer> fifo = new CircularFifoQueue<Integer>(3);
public Queue<Integer> getChannelNumbers() {
return fifo;
}
public Integer getChannelNumber() {
return fifo.isEmpty() ? null : fifo.peek();
}
public void addToChannelsHistory(int channnelNumber) {
fifo.add(channnelNumber);
}
public String toString() {
return fifo.toString();
}
public static void main( String[] args ) {
TV tv = new TV();
tv.addToChannelsHistory(11);
tv.addToChannelsHistory(22);
tv.addToChannelsHistory(33);
tv.addToChannelsHistory(44);
tv.addToChannelsHistory(55);
System.out.print( tv );
}
}
Forgive me if I've misunderstood, but as far as I can tell by copying this locally, this works. However, in a Java program, the main method is the entry point into the program. If you aren't instantiating your TV class in the main method, the addToChannelHistory method will never get run. For instance, this works for me:
public class TV {
public int channelNumber = 11;
public int getChannelNumber() {
return channelNumber;
}
public void addToChannelsHistory(int channnelNumber) {
Queue<Integer> fifo = new CircularFifoQueue<Integer>(3);
fifo.add(channnelNumber);
System.out.print(fifo);
}
public static void main(String[] args) {
TV tv = new TV();
tv.addToChannelsHistory(11);
tv.addToChannelsHistory(22);
tv.addToChannelsHistory(33);
tv.addToChannelsHistory(44);
tv.addToChannelsHistory(55);
}
}
Running that program should print out 33 to the console.
Related
I'm having a fairly odd problem with Netbeans.
I'm trying to calculate the sum of an ArrayList, but I am not able to call the method public int sumOfHand() onto my this.hands variable.
I've restarted Netbeans numerous times, created new classes and tried to calculate the sum using the .reduce() method using streams, but none of it helped.
Thanks for any suggestion!
import java.util.List;
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.Collections;
public class Hand implements Comparable<Hand>{
public ArrayList<Card> hands;
public Hand() {
this.hands = new ArrayList<>();
}
public void add(Card card) {
this.hands.add(card);
}
public void print() {
this.hands.forEach(crd -> {System.out.println(crd);});
}
public void sort() {
Collections.sort(this.hands, (crd1, crd2) -> crd1.compareTo(crd2));
}
#Override
public int compareTo(Hand otherHand) {
// sumOfHand() not recognized here, 'Cannot find symbol'
return this.hands.sumOfHand() - otherHand.sumOfHand();
}
public int sumOfHand() {
int sum = 0;
for (Card tc : this.hands) {
sum += tc.getValue();
}
return sum;
}
}
You can't call a int sumOfHand() of this.hands as hands is an ArrayList.class and int sumOfHand() is a method of Hand.class. To call this method you need to use this.sumOfHands() inside your Hand.class.
I wrote a small application that receives data from a web socket, which I store in static ConcurrentSkipListMap.
The application initially creates a new thread where it runs infinitely while loop calling ConcurrentSkipListMap.firstKey(). After a while, this call throws a NoSuchElementException, even though the ConcurrentSkipListMap contains data.
break point in catch block
Example of my application:
I have cacher class that contains websocket implementation and NavigableMap init:
package solvethat.net.triobot.Example;
import com.binance.api.client.BinanceApiCallback;
import com.binance.api.client.BinanceApiClientFactory;
import com.binance.api.client.domain.event.DepthEvent;
import com.binance.api.client.domain.market.OrderBook;
import com.binance.api.client.domain.market.OrderBookEntry;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
public class AskCacher {
private long updateId;
private final BinanceApiClientFactory factory;
public AskCacher() {
factory = BinanceApiClientFactory.newInstance();
initAsks();
runWebsocket();
}
/**
* Init data getting order book snapshot
*/
private void initAsks() {
try {
OrderBook orderBook = factory.newRestClient().getOrderBook("btcusdt".toUpperCase(), 10);
updateId = orderBook.getLastUpdateId();
NavigableMap<Double, Double> asks = new ConcurrentSkipListMap<>(Comparator.naturalOrder());
for (OrderBookEntry ask : orderBook.getAsks()) {
asks.put(Double.parseDouble(ask.getPrice()), Double.parseDouble(ask.getQty()));
}
StaticData.ask = asks;
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
private void runWebsocket() {
factory.newWebSocketClient().onDepthEvent("btcusdt", new BinanceApiCallback<>() {
/**
* Set ask price and call analysis method
*/
#Override
public void onResponse(DepthEvent depthEvent) {
if (depthEvent.getFinalUpdateId() > updateId) {
updateId = depthEvent.getFinalUpdateId();
updateOrderBook(depthEvent.getAsks());
}
}
/**
* Just print err message
*/
#Override
public void onFailure(final Throwable cause) {
System.err.println(cause.getMessage());
}
});
}
/**
* Updates an order book (asks) with a delta received from the server.
* Whenever the qty specified is ZERO, it means the price should was removed from the order book.
*/
private void updateOrderBook(List<OrderBookEntry> orderBookDeltas) {
for (OrderBookEntry orderBookDelta : orderBookDeltas) {
Double price = Double.parseDouble(orderBookDelta.getPrice());
BigDecimal qty = new BigDecimal(orderBookDelta.getQty());
if (qty.compareTo(BigDecimal.ZERO) == 0) {
// qty=0 means remove this level
StaticData.ask.remove(price);
} else {
StaticData.ask.put(price, Double.parseDouble(orderBookDelta.getQty()));
}
}
// Print best ask to see if cacher is alive
System.out.println("btc-usdt best ask: " + StaticData.ask.firstKey());
// Edit map length
if (StaticData.ask.size() > 10) {
StaticData.ask.tailMap((Double) StaticData.ask.keySet().toArray()[10], true).clear();
}
}}
Then infinite loop:
package solvethat.net.triobot.Example;
public class InfiniteLoop {
public void loopProcess() {
Analyzer analyzer = new Analyzer();
while (true) {
analyzer.analyze(StaticData.ask.firstEntry());
}
}}
And analyzer class:
package solvethat.net.triobot.Example;
import java.util.Map;
public class Analyzer {
public void analyze(Map.Entry<Double, Double> entry) {
StaticData.AnalyzeObject analyzeObject = new StaticData.AnalyzeObject();
analyzeObject.setBestAsk(entry.getKey());
if (analyzeObject.getBestAsk() > 50000) {
System.out.println("It is a good price!!");
}
}
}
Static data model:
package solvethat.net.triobot.Example;
import java.util.NavigableMap;
public class StaticData {
public static NavigableMap<Double, Double> ask;
public static class AnalyzeObject {
double bestAsk;
public double getBestAsk() {
return bestAsk;
}
public void setBestAsk(double bestAsk) {
this.bestAsk = bestAsk;
}
}
}
Main class for example run:
package solvethat.net.triobot.Example;
public class Main {
public static void main(String[] arguments) {
new AskCacher();
new Thread(new InfiniteLoop()::loopProcess).start();
}
}
The example only shows how the application is composed, but I was not able to use it to raise an error but I opened my repo as public:
https://github.com/Sick-E/TrioBot
Can anyone please help me?
Thank you.
Tomas
You can replace your code with something like that (no exception handling is required)
Optional.ofNullable(trio.getThirdPair().getBids().firstEntry())
.map(Map.Entry::getKey)
.ifPresent(trio.getTrioAnalysis()::setBidThird);
public class XObject {
...
}
public class XObjectWrapper
{
private final XObject xo;
public XObjectWrapper(XObject xo) {
this.xo = xo;
}
//delegated methods
...
}
I have List<XObject>, I want to get List<XObjectWrapper>.
Obviously, I can do something like this:
List<XObjectWrapper> wrappedList = new ArrayList<XObjectWrapper> ();
for(XObject xo : xoList)
{
wrappedList.add(new XObjectWrapper(xo));
}
Can I use some new java8 feature, and do it with a single line?
This will do:
List<XObjectWrapper> wrappedList =
xoList.stream().map(XObjectWrapper::new).collect(toList());
(Assuming import static java.util.stream.Collectors.toList;)
Update
For completeness, and due to possible errors in your code, here is a self-contained example:
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.List;
static class XObjectWrapper {XObjectWrapper(Object o) {}}
static class XObject {}
public class Test {
public static void main(String[] args) {
List<Object> xoList = new ArrayList<>();
List<XObjectWrapper> wrappedList =
xoList.stream().map(XObjectWrapper::new).collect(toList());
System.out.println(wrappedList);
}
}
I have a static HashMap to which I'm adding a new item like so:
public static void addSession(Session session) {
if(!map.containsKey(session)){
map.put(session, new SessionThread(session));
}
}
SessionThread is declared locally like so:
public class SessionThread implements Runnable {
That map.put line has a compile error of non-static variable this cannot be referenced from a static context. What is causing the error? this is not referenced anywhere in that method, let alone any non-static members. Everything is either static or in the scope of the method.
Entire class...
package me.scratchjava;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
/**
* A class for managing websocket threads.
* #author James Smyth <jimsmyth at datafascia.com>
*/
public class SessionManager {
private static HashMap<Session, SessionThread> map = new HashMap<>();
/**
* Called whenever a new websocket is opened.
* #param session
*/
public static void addSession(Session session) {
if(!map.containsKey(session)){
map.put(session, new SessionThread(session));
}
}
public static void removeSession(Session session){
if(map.containsKey(session)){
map.remove(session);
}
}
public static void sendData(Session session, byte[] bytes){
if(map.containsKey(session)){
map.get(session).send(bytes);
}
}
public class SessionThread implements Runnable {
private Session session;
private boolean alive = true;
private final LinkedList<byte[]> messageQueue = new LinkedList<>();
public SessionThread(Session session){
}
#Override
public void run() {
while (alive) {
if(Thread.interrupted()){
alive = false;
return;
}
synchronized (messageQueue) {
while(!messageQueue.isEmpty()){
byte[] msg = messageQueue.poll();
try {
session.getBasicRemote().sendBinary(ByteBuffer.wrap(msg));
} catch (IOException ex) {
Logger.getLogger(SessionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
public void send(byte[] bytes) {
synchronized (messageQueue) {
messageQueue.add(bytes);
}
}
public void kill(){
alive = false;
}
}
}
Your SessionThread inner class is not static. That means the compiler generates a constructor to capture the value of this, the enclosing class. Since you're trying to create a new SessionThread in a static method, there is no this to capture. Make the class static.
Edit
#directedition: SessionThread should be a static class. Actually it should be a stand alone interface and class.
I have a model which can be modified at run time. Here's an example :
public class JavaMethod
{
private String name;
private List<Parameter> parameters;
private boolean isConstructor; // this is an example
}
The parameters can have different type (integer, boolean, string, float...) and different valid values. For example, an integer parameter named age could only hold positive integers.
The problem is that I would like to generate a view with Swing to configure that JavaMethodobject, but I am not sure of the proper way to do it.
For example, the age parameter which is a positive integer would be linked to a class extending JTextField that prevent entering negative any letters. Another integer parameter named numberOfFingers which can range from 8 to 12 would be linked to a class extending JComboBox that allows selection of an option in that range.
I could do this with polymorphism by giving the task of generating the appropriate Swing component to the Parameter object, but then my model would know about how the view is generated.
What is the proper way of generating a view for a model like this?
All I can think of (without the model involved in the generation of the view) is a kind of giant switch in the controller that picks the good component by reading the Parameter's details.
Thanks
For that you are needed to create Customized PlainDocument . For example for JTextField containing only age value you should create AgeDocument class which would look something like this :
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
class AgeDocument extends PlainDocument
{
#Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
{
/**Write your logic here**/
if (str == null)
{
return;
}
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++)
{
if (!Character.isDigit(arr[i]))//Checking for Non Numeric.
{
return;
}
if (Character.getNumericValue(arr[i])==0 )
{
try
{
int val = Integer.parseInt(getText(0,offs));
if (val == 0)
{
super.insertString(offs,"", a);//Don't allow to put 0 as age.
return;
}
}
catch (Exception ex){return;}
}
}
super.insertString(offs, new String(str), a);
}
}
And whenever you want to set this AgeDocument property to a JTextField object you simply write JTextFieldOBject.setDocument(new AgeDocument ())
Likewise , you can create many model independently. And can use them anywhere in your code.
The best way to solve this problem is to use the Visitor Pattern.
For example :
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class Main
{
public static class JavaMethod implements Iterable<Parameter>
{
private List<Parameter> parameters;
public JavaMethod()
{
this.parameters = new ArrayList<>();
// This is an example
this.parameters.add(new IntegerParameter());
this.parameters.add(new StringParameter());
}
#Override
public Iterator<Parameter> iterator()
{
return this.parameters.iterator();
}
}
public static interface Parameter
{
public void accept(ParameterVisitor visitor);
}
public static class IntegerParameter implements Parameter
{
public int value = 10;
#Override
public void accept(final ParameterVisitor visitor)
{
visitor.visit(this);
}
}
public static class StringParameter implements Parameter
{
public String value = "Hello";
#Override
public void accept(final ParameterVisitor visitor)
{
visitor.visit(this);
}
}
public static interface ParameterVisitor
{
void visit(StringParameter stringParameter);
void visit(IntegerParameter integerParameter);
}
public static class ParameterSwingVisitor implements ParameterVisitor
{
private final JComponent container;
public ParameterSwingVisitor(final JComponent container)
{
this.container = container;
}
#Override
public void visit(final StringParameter stringParameter)
{
this.container.add(new JTextField(stringParameter.value));
}
#Override
public void visit(final IntegerParameter integerParameter)
{
// This could be a custom component to pick numbers
this.container.add(new JLabel(String
.valueOf(integerParameter.value)));
}
}
public static void main(final String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
JPanel myPanel = new JPanel(); // view
JavaMethod myMethod = new JavaMethod(); // model
final ParameterVisitor visitor = new ParameterSwingVisitor(
myPanel);
for (final Parameter picked : myMethod)
{
picked.accept(visitor); // This will add the appropriate
// swing
// component
}
JFrame myFrame = new JFrame("Visitor pattern");
myFrame.setContentPane(myPanel);
myFrame.setVisible(true);
myFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
myFrame.setSize(500, 500);
}
});
}
}
More information about this pattern here.