Greetings,
I have one simple condition that never passes:
if(datas.date.getTime()-temps.date.getTime()>=5000)
I want to check if it has been 5 seconds from one to another.
Update:
Here is setter and getter:
public class Data{
Date date;
public Date getDate() {
return date;
}
public void setDate() {
Date now = new Date();
this.date = now;
}
}
So, I call
Data data;
data.setDate();
processValues(data);
this is processValues:
public void processValues(Data dat){
if(datas.size()==7){
writeValues(datas);
datas=new Vector<Data>();
temps=new Vector<Data>();
}
temps.add(dat);
datas.add(dat);
}
this is writeValues:
public void writeValues(Vector<Data> datas){
for(i=0;i<temps.size();i++)
for(j=0;j<datas.size();j++){
if(temps.elementAt(i).epc==datas.elementAt(j).epc)
if(datas.elementAt(j).date.getTime()-temps.elementAt(i).date.getTime()>=5000)
try {
dao.writeToDatabase(datas.elementAt(j));
i=j;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
If you output datas.date.getTime() and temps.date.getTime(), which one is higher? My guess is that they are reversed and the subtraction is giving a negative number - which of course would never be greater than 5000. Or the data points aren't 5 seconds apart.
You said that your processValues() method looks like this:
public void processValues(Data dat){
if(datas.size()==7){
writeValues(datas);
datas=new Vector<Data>();
temps=new Vector<Data>();
}
temps.add(dat);
datas.add(dat);
}
You're adding the same instance ("dat") to both vectors. If you update one it will necessarily update the other, so there can never be a difference in the date field.
You say you have a getter that looks like this:
public Date getDate() {
return date;
}
Date objects are mutable, so you should probably copy defensively. You can use clone() for this.
Based on that and the syptoms of your problem, perhaps your two Date objects are actually the same object. Have you tried using == (or !=) to confirm that they are indeed separate objects?
Update
Based on the updated information I can see why that condition never passes. I don't really understand what you want you code to do, however. You're essentially just testing if you can create 7 objects in less than 5 seconds, and if you can't then you write some of them out. Either way you clear temps and datas, whether you wrote the objects out or not. My guess is that you do not want to clear these vectors of elements that were not written out. I also don;t understnad why you have both datas and temps when they contain exactly the same elements.
Related
I have one singleton object which actually store user activity. I wanted to remove this data on certain time ( at every night 12 ). I wanted to know How we can achieve this with out having different thread running.
Add a method to the singleton that returns the last date it ran:
static Date lastRun = new Date(); //when the class initializes
Date lastDateRan() {
return lastRun;
}
Then add another method that checks if today > lastRun (pay attention to check only the date - not time/hour - in case you decide to use TimeStamp or any other library).
Whenever the object is called, check:
if (today > lastRun) {
lastRun = today;
// and clean the object.
}
It won't run every-day exactly at midnight, but it'll have the exact same effect! (the first call after midnight will get "fresh" data)
You can use following code :
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
Object_name.close //your code to cleanup object
}
},
12*60*60*1000 /*time after which it will run again*/
);
Which would you consider more efficient?
The use of 'WeekDay' is just an example:
public enum WeekDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
}
Loop through and verify day string first:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; // day 'should' always be a weekday
if (isValidWeekDay(day)) {
WeekDay weekDay = WeekDay.valueOf(day); // won't throw exception
...
} else {
throw new InvalidWeekDayException(day); // subclass of RuntimeException
}
}
private boolean isValidWeekDay(String day) {
for (WeekDay weekDay : WeekDay.values()) {
if(weekDay.toString().equals(day))
return true;
}
return false;
}
Or since in 99.99% of cases, day will be correct:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; // day 'should' always be a weekday
try {
WeekDay weekDay = WeekDay.valueOf(day); // might throw exception
...
} catch (IllegalArgumentException e) {
throw new InvalidWeekDayException(day, e);
}
}
Update:
To clarify, the input string will come from a client application, rather than a user. So in other words, it would be a bug to recieve a non workday in this example.
As has been commented, you will have to profile to find out for sure. Even in your own parsing approach, you can make it faster by returning the enum when you parse the list.
private WeekDay getValidWeekDay(String day) {
for (WeekDay weekDay : WeekDay.values()) {
if(weekDay.toString().equals(day))
return weekDay;
}
return null;
}
Unless this is a time critical piece of an application, I wouldn't worry about it in either case and simply take the most readable approach. I think that would be using the WeekDay.valueOf() method.
If you would rather not have to deal with exceptions, then create a Map of your values within the enum and effectively do the equivalent of valueOf() from a lookup which returns null if it is not found.
public enum WeekDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
private static Map<String, WeekDay> valueMap;
public static WeekDay getValue(String possibleName)
{
if (valueMap == null)
{
valueMap = new HashMap<String, WeekDay>();
for(WeedDay day: values())
valueMap.put(day.toString(), day);
}
return valueMap.get(possibleName);
}
}
This is effectively what the valueOf() method is doing anyway, except it throws the IllegalArgumentException when it is not found. This approach will simply return null, thus not generating the stacktrace.
What is the performance concern about the 2nd approach? Catching an exception like that costs almost nothing. Using exceptions for normal control flow is generally a bad idea from a design perspective, the days where this was a performance consideration are long gone. In a debugger, using exceptions as significant control operations will slow things down by a factor of about 10. But this gets optimized by the JIT and there is no measurable impact in production.
These numbers are based on experience with an evaluation I did of the zxing project, which uses exceptions for all sorts of flow control. When I first saw it, I was horrified. I still think it's not the best design, but I did quite a bit of testing and can say with a good bit of confidence that it had no real impact on performance. And this is an algorithm that was using exceptions all over the place for flow control. Your situation, where the exception will only get thrown in highly exceptional circumstances, is a non issue.
Edit: I've had a downvote or two on my answer, and I want to make sure that I'm super clear on what I'm saying: I do not think that it's a good idea to use exceptions for normal control flow. Just because performance is not a good argument for not using exceptions this way doesn't mean that there aren't other, perfectly valid reasons (such as readability, testability, extendability). In the case of the OP, the use of an exception is absolutely called for, and definitely wouldn't cause any sort of performance issue.
I know its an old post, but I believe following result will be still interesting. I run 10000000 tests to find an element in enum ENUM {FIRST, SECOND, THIRD, FOURTH, LAST} using JDK 1.8. The table below shows time required by simple loop and valueOf().
text loop valueOf ratio
------------------------------
"FIRST" 121 65 186%
"LAST" 188 57 330%
"foo" 155 8958 1.7%
Conclusion - I wouldn't use valueOf() if I expect values not matching enum.
If your question is really about the efficiency of searching among 7 item you have already wasted too much time on it. Even the fastest search algorithms yield zero or negative benefits until N > 15 or so, other than the O(1) one.
Store the valid strings in a HashSet, and decide whether a string is a valid day or not based on Set.contains(...).
The set can be a static final Set, and you can wrap in an unmodifiable for good measure:
private static final Map<String> WEEKDAY_STRINGS;
static {
HashSet<String> set = new HashSet();
for (WeekDay d : WeekDay.values()) {
set.add(d.toString());
}
WEEKDAY_STRINGS = Collections.unmodifiableSet(set);
}
The loop doesn't do anything that calling valueof doesn't, they have the same functionality : checking whether your string is valid enum. What do you think you gain from the first option ?
The second option is best:
try {
WeekDay weekDay = WeekDay.valueOf(day); // might throw exception
...
} catch (IllegalArgumentException e) {
throw new InvalidWeekDayException(day);
}
Or you could create a lookup of enum values inside your enum when the class first loads(see static modifier) and validate using get() as shown below:
private String dayName;
private static final Map<String,Weekday> lookup = new HashMap<String, Weekday>();
static{
for (Weekday day: values()){
lookup.put(day.dayName, d);
}
}
public static Weekday get(String _name){
return lookup.get(_name);
}
Let me know if you need more details
I have this method to test :
public static Date getDateSinceUTC(CstOrderBean orderBean) {
int year = orderBean.getDeadLineYear();
int month = orderBean.getDeadLineMonth();
int day = orderBean.getDeadLineDay();
int hour = orderBean.getDeadLineHour();
int minute = orderBean.getDeadLineMinute();
String ap = orderBean.getDeadLineAmPm() == 1 ? "PM" : "AM";
//TODO AM=0, PM=1 comes from html form
SimpleDateFormat df = new SimpleDateFormat("yyyy:MM:dd:hh:mm:aa");
String stringDate = stringifyIntegers(":", year, month, day, hour, minute);
stringDate = stringDate.concat(ap);
Date date;
try {
date = df.parse(stringDate);
} catch (ParseException e) {
throw new Error("Parsing date from html form failed", e);
}
return date;
}
Where CstOrderBean needs to be mocked by Mockito because it is not a POJO (some static initializations etc. - from source code generator). But I need to run the method xxx times, hence set the mocks with many data combinations
I could use TestNG's #DataProvider to do that. But I'm not sure how to do that, I guess that :
when(ob.getDeadLineYear()).thenReturn(1, 2, 3);
....
in loop is a bad idea, isn't it ? Is the correct way of doing this to create xx mocks and initialize them like that ?
Each test should get their own mock that preferably does not have variable data. If you use several different return values from the same mock object then the testing has to be white-box testing as the test is coupled with the number of calls to a mocked method instead of the result of the method under test.
That said, you are able to define a set of return values with calling thenReturn repeatedly or by defining the return values as varargs
when(ob.getDeadLineYear()).thenReturn(someValue, anotherValue, ..., ultimateValue);
This might be cleaner as you should probably control the values that the mock returns anyway.
How you mock depends on what you would like to test. Looping on the deadline year might not do the job you want it to.
One test for seeing if a leap year works might be something like:
when(ob.getDeadLineYear()).thenReturn(2000);
when(ob.getDeadLineMonth()).thenReturn(2);
when(ob.getDeadLineDay()).thenReturn(29);
when(ob.getDeadLineHour()).thenReturn(12);
when(ob.getDeadLineMinute()).thenReturn(0);
when(ob.getDeadDeadLineAmPm()).thenReturn(1);
assertTrue("Got unexpected date", getDateSinceUTC(ob).toString().startsWith("2000-02-29 12:00:00"));
(Warning: above codes was typed in by hand). Mix, match, and repeat for other dates that you need to test to verify that getDateSinceUTC is working. You might want a separate test method to check invalid dates, like 2/30/2012 (and expect a throw). You might want to check invalid times like 23:61. You might want to check valid dates, like your birthdate.
Instead of a loop on the year, please look at "normal" cases, borderline cases, and error cases. This is the better practice for unit testing.
I want to have thread save method that returns a unique current Timestamp.Even when the method is called by same time i want to get a unique current datetime.Even if this method is called by making multiple instances of MyClass i want it be be thread safe always
class Myclass{
Date getUniquetimeStam(){
synchronized(Myclass.class){
//return date here
}
}
Now if i make 2 instances of Myclass and call getUniqueStam at same ,is it gaurented to return uniue date time.
You can't guarantee unique time for each call. But you can for instance increment it manually if it didn't change yet:
private AtomicLong lastTime = new AtomicLong();
long getUniquetimeStam() {
while (true) { // way of working with atomics, but they are really fast
long now = System.currentTimeMillis();
long last = lastTime.get();
if (last < now) {
if (lastTime.compareAndSet(last, now))
return now;
} else
return lastTime.incrementAndGet();
}
}
No, you are not guaranteed. If your computer is fast enough then both method calls can happen in same millisecond and produce identical Date object.
You have 2 options here:
Use UUID instead of date. Read more about it here . UUID by specification is guaranteed to be unique each time you generate it - so it's the safest and easiest option you can get.
Store the date object, synchronize on it, and check if it's the same. Here's an example:
.
class Myclass {
//Static to make it possible to synchronize between instances of Myclass
static Date lastDate;
Date getUniqueTimeStamp() {
synchronized (Myclass.lastDate) {
Date newDate = new Date();
if (newDate.getTime() <= Myclass.lastDate.getTime()) {
newDate.setTime(Myclass.lastDate.getTime()+1);
}
Myclass.lastDate.setTime(newDate.getTime());
return newDate;
}
}
}
Not cool though - you can add a delay and then create the Data.
class Myclass {
Date getUniquetimeStam() {
//in try catch
Thread.sleep(100);
//
new Date();
}
}
Could you just change it to return a new instance of Date on every call?
class Myclass {
Date getUniquetimeStam() {
new Date();
}
}
Is there some sort of exception in Java to catch an invalid Date object? I'm trying to use it in the following method, but I don't know what type of exception to look for. Is it a ParseException.
public boolean setDate(Date date) {
this.date = date;
return true;
}
In the method you provide, there is no way to catch an exception, because none will be thrown by the simple assignment. All you can do is maybe the below change:
if(date == null) return false;
But even that's not graceful. You may want to do something with this.date or throw an exception up if that's the desired behavior.
What you are really seeking is either:
ParseException - thrown by a DateFormat object when it attempts to parse(), which would happen before your set method
IllegalArgumentException - thrown by a SimpleDateFormat constructor, again it would happen before your set method. Indicates you provided an invalid format string.
You'd want to catch one of those (probably #1). But it has to happen before your method call. Once you have a Date object, it is either null or valid.
This might not be related to the original question. But you must notice the method name, which is setDate(). Do you think it sounds like it will return something? Or if it may, then do you think its a good idea to return a boolean there? IMO, do something like this,
public void setDate(Date date) {
this.date = date;
}
public boolean isDateNull() { // or something
return this.date == null;
}
In this method, there is no need to worry about an exception. The date is already created by the time you get into this method. If you are parsing a date, it would have done outside of this code. The best you could do is make sure the date is not null.
It depends on what you mean by an invalid date. Did you mean to give us a method signature that looked more like this?
public void setDate(String date) throws ParseException {
this.date = SomeDateFormat.getInstance().format(date);
}
Otherwise, as the others stated the simple act of assigning a Java date object to a field shouldn't be exceptional as it is either an instance of Date already, or null.
If you are just trying to parse a string into a java.util.Date, look at DateFormat, FastDateFormat (apache, thread safe), or Joda Time.