I have a problem. I have the following class:
public class Cross implements Comparable<Cross> { private Long openTime; private String market; private String coin; private String period; private String metric1; private String metric2; private Double close; private String trend; public Long getOpenTime() { return this.openTime; } public void setOpenTime(long openTime) { this.openTime = openTime; } public String getMarket() { return this.market; } public void setMarket(String market) { this.market = market; } public String getCoin() { return this.coin; } public void setCoin(String coin) { this.coin = coin; } public String getPeriod() { return this.period; } public void setPeriod(String period) { this.period = period; } public String getMetric1() { return this.metric1; } public void setMetric1(String metric1) { this.metric1 = metric1; } public String getMetric2() { return this.metric2; } public void setMetric2(String metric2) { this.metric2 = metric2; } public Double getClose() { return this.close; } public void setClose(double close) { this.close = close; } public String getTrend() { return this.trend; } @Override public boolean equals(Object object) { if (object != null && object instanceof Cross) { Cross cross = (Cross) object; return ( openTime.equals(cross.getOpenTime()) && market.equals(cross.getMarket()) && coin.equals(cross.getCoin()) && period.equals(cross.getPeriod()) && metric1.equals(cross.getMetric1()) && metric2.equals(cross.getMetric2()) ); } return false; } @Override public int compareTo(Cross o) { return this.getOpenTime().compareTo(o.getOpenTime()); } }
Now I have a list containing 500 objects of these elements. Here are the first 4 shown:
{ openTime='1504332000000', market='USDT', coin='ETH', period='2h', metric1='EMA12', metric2='EMA26', close='363.7', trend='Down'} { openTime='1504663200000', market='USDT', coin='ETH', period='2h', metric1='EMA12', metric2='EMA26', close='325.73', trend='Up'} { openTime='1504879200000', market='USDT', coin='ETH', period='2h', metric1='EMA12', metric2='EMA26', close='294.05', trend='Down'} { openTime='1505181600000', market='USDT', coin='ETH', period='2h', metric1='EMA12', metric2='EMA26', close='304.41', trend='Up'}
In a variable I have stored the epoch of a specific datetime and with that I want to find the first valid cross, so I tried this:
private Cross getValidCross(List<Cross> crossList, LocalDateTime runDateTimeGMT0) { long searchEpoch = runDateTimeGMT0.toEpochSecond(ZoneOffset.UTC) * 1000; return crossList.stream().filter(cross -> cross.getOpenTime() < searchEpoch).max(Cross::compareTo).orElse(null); }
But this code returns the value null
When my searchEpoch
is for example: 1514764800000
. In the list I do see multiple objects that have a lower openTime
than the searchEpoch
. The result I want is the cross with the highest openTime
, but it still has to be smaller than the searchEpoch
.
Here is the error I get:
runDateTimeGMT0: 2018-01-01T00:00 Exception in thread "main" java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.hatop.drivers.SimulatorDriver.run(SimulatorDriver.java:297) at com.hatop.drivers.HatopDriver.main(HatopDriver.java:120) Caused by: java.lang.NullPointerException: Cannot invoke "com.hatop.models.Cross.getTrend()" because the return value of "com.hatop.drivers.HatopDriver.getValidCross(List<Cross>, LocalDateTime)" is null at com.hatop.strategies.modules.module_java001.run(module_java001.java:186) ... 6 more
Why is my return value null
?
Advertisement
Answer
This is caused due to the value the argument runDateTimeGMT0
is given and this:
long searchEpoch = runDateTimeGMT0.toEpochSecond(ZoneOffset.UTC) * 1000;
Since this is working:
public class Demo { private static Cross getValidCross(List<Cross> crossList, LocalDateTime runDateTimeGMT0) { long searchEpoch = 1514764800000L; return crossList.stream() .filter(cross -> cross.getOpenTime() < searchEpoch) .max(Cross::compareTo) .orElse(null); } @SneakyThrows public static void main(String[] args) { List<Cross> crosses = Arrays.asList( new Cross(1504332000000L, "USDT", "ETH", "2h", "EMA12", "EMA26", 363.7, "Down"), new Cross(1504663200000L, "USDT", "ETH", "2h", "EMA12", "EMA26", 325.73, "Up"), new Cross(1504879200000L, "USDT", "ETH", "2h", "EMA12", "EMA26", 294.05, "Down"), new Cross(1505181600000L, "USDT", "ETH", "2h", "EMA12", "EMA26", 304.41, "Up") ); Cross validCross = getValidCross(crosses, null); System.out.println(validCross); } }
Output:
Cross(openTime=1505181600000, market=USDT, coin=ETH, period=2h, metric1=EMA12, metric2=EMA26, close=304.41, trend=Up)
By the way, equals()
is implemented without hashcode()
– a recipe for problems.