Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » Java rant. Or is there a pretty workaround?

Credits go to MiquelFire for helping out!
This thread is locked; no one can reply to it. rss feed Print
Java rant. Or is there a pretty workaround?
type568
Member #8,381
March 2007
avatar

public NewCandle(String line){
        Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS);
        Matcher m=p.matcher(line);
        this=new NewCandle(null);
        if(m.find())
            this(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9));
        else{
            GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line.");
            this(null,null,null,null,null,null,null,null,null);
        }
    }

The other constructor is capable of taking nine Strings representing these groups..
It really is no hard to code it without the reference to it, but.. Come on! It is so much prettier to refer to it. However..

error: call to this must be first statement in constructor

Which actually doesn't surprise me, I remember it from the old good days during which I studying on the university not even knowing what a OHLC* is. But Jesus, is there no work around better than copy-pasting my code?

Only thing I can think about is a static Method which is gonna return that NewCandle, which well.. Implies different functionality a little.

*- Open, High, Low, Close. What represents a single candle on a chart of more or less any financial instrument tradable on an exchange.

torhu
Member #2,727
September 2002
avatar

Which line is the problem?

type568
Member #8,381
March 2007
avatar

Two errors, both calls to this(..).
In this code it'd be 6 & 9. In my file it's 129 & 140. As result also 142(11), as a set of final fields were not initialized.

torhu
Member #2,727
September 2002
avatar

Use an array or an ArrayList?

APPEND: Uh, what you are doing doesn't look like Java to me. Why are you assigning to this?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

type568
Member #8,381
March 2007
avatar

:)

this() is a call to a constructor. That is, my constructor taking a single String, is parsing this string to nine other strings, and intends to pass them on to another constructor.

A larger chunk of the code looks like this:

#SelectExpand
1public NewCandle(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year){ 2 _data=new BigDecimal[7]; 3 _data[TYPE.CLOSE.ordinal()]=open; 4 _data[TYPE.OPEN.ordinal()]=high; 5 _data[TYPE.HIGH.ordinal()]=low; 6 _data[TYPE.LOW.ordinal()]=close; 7 _data[TYPE.CHANGE.ordinal()]=change; 8 _data[TYPE.VOLUME.ordinal()]=volume; 9 10 DATE= new MyDate(day,month,year); 11 } 12 13 public NewCandle(float open,float high,float low,float close,float change,long volume,int day,int month,int year){ 14 this(new BigDecimal(open),new BigDecimal(high),new BigDecimal(low),new BigDecimal(close),new BigDecimal(change),new BigDecimal(volume),day,month,year); 15 } 16 17 public NewCandle(String open,String high,String low,String close,String change,String volume,String day,String month,String year){ 18 this(Float.parseFloat(open),Float.parseFloat(high),Float.parseFloat(low),Float.parseFloat(close),Float.parseFloat(change),Long.parseLong(volume),Integer.parseInt(day),Integer.parseInt(month),Integer.parseInt(year)); 19 } 20 21 public NewCandle(String line){ 22 Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); 23 Matcher m=p.matcher(line); 24 this=new NewCandle(null); 25 if(m.find()) 26 this(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9)); 27 else{ 28 GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line."); 29 this(null,null,null,null,null,null,null,null,null); 30 } 31 }

Nope, what Edgar suggests returns with an error saying this is final(an analogue of CONST of C , IIRC).

P.S:
I'm unsure myself why it's BigDecimal, could as well be just floats(there is way more than enough precision for a price of a stock).. But well, what Yahoo returns is BigDecimal, so whatever..

torhu
Member #2,727
September 2002
avatar

You can't assign to this in Java. What compiler are you running your code through?

MiquelFire
Member #3,110
January 2003
avatar

I think for times like this, you would need an init function of sorts.

Something like this:

#SelectExpand
1public NewCandle(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year){ 2 init(open,high,low,close,change,volume,day,month,year); 3 } 4 5 public NewCandle(float open,float high,float low,float close,float change,long volume,int day,int month,int year){ 6 init(new BigDecimal(open),new BigDecimal(high),new BigDecimal(low),new BigDecimal(close),new BigDecimal(change),new BigDecimal(volume),day,month,year); 7 } 8 9 public NewCandle(String open,String high,String low,String close,String change,String volume,String day,String month,String year){ 10 init(Float.parseFloat(open),Float.parseFloat(high),Float.parseFloat(low),Float.parseFloat(close),Float.parseFloat(change),Long.parseLong(volume),Integer.parseInt(day),Integer.parseInt(month),Integer.parseInt(year)); 11 } 12 13 public NewCandle(String line){ 14 Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); 15 Matcher m=p.matcher(line); 16 if(m.find()) 17 init(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9)); 18 else{ 19 GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line."); 20 init(null,null,null,null,null,null,null,null,null); 21 } 22 } 23 24 25private void init(BigDecimal open,BigDecimal high,BigDecimal low, BigDecimal close,BigDecimal change,BigDecimal volume,int day,int month,int year) { 26 _data=new BigDecimal[7]; 27 _data[TYPE.CLOSE.ordinal()]=open; 28 _data[TYPE.OPEN.ordinal()]=high; 29 _data[TYPE.HIGH.ordinal()]=low; 30 _data[TYPE.LOW.ordinal()]=close; 31 _data[TYPE.CHANGE.ordinal()]=change; 32 _data[TYPE.VOLUME.ordinal()]=volume; 33 34 DATE= new MyDate(day,month,year); 35}

---
Febreze (and other air fresheners actually) is just below perfumes/colognes, and that's just below dead skunks in terms of smells that offend my nose.
MiquelFire.red
If anyone is of the opinion that there is no systemic racism in America, they're either blind, stupid, or racist too. ~Edgar Reynaldo

type568
Member #8,381
March 2007
avatar

@torhu tbh I'm clueless what's under the hood of the IDE, which is.. Oh:

Product Version: NetBeans IDE 8.0.2 (Build 201411181905)
Updates: NetBeans IDE is updated to version NetBeans 8.0.2 Patch 2
Java: 1.8.0_45; Java HotSpot(TM) 64-Bit Server VM 25.45-b02
Runtime: Java(TM) SE Runtime Environment 1.8.0_45-b15
System: Windows 7 version 6.1 running on amd64; Cp1251; en_US (nb)
User directory: C:\Users\type568\AppData\Roaming\NetBeans\8.0.2
Cache directory: C:\Users\type568\AppData\Local\NetBeans\Cache\8.0.2

@MiquelFire

Yeah well. Your approach is way better than what I thought about with making an public static creator of the class, and well.. It sure is better than copying. But still sad, my approach is the most elegant out there, and it just doesn't work cos' they said so.

I suppose I'll go with Miquel's suggestion, thanks.

Append: I won't be implementing it right now, but now I do wonder if the compiler gonna see I did assign values to all final fields.. It may not :)

torhu
Member #2,727
September 2002
avatar

You cannot assign to this. Remove that part of your code and see what happens. Also, wait until the mushrooms wear off until you do any more programming ::)

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Elias
Member #358
May 2000

type568 said:

Your approach is way better than what I thought about with making an public static creator of the class,

I think that actually is close to what the true Java way would be. Just have your creator ("factory") live in a separate class. Remember, in Java, the more separate classes you can come up with to implement a task the better:

class NewCandleFactory {
    public NewCandle makeNewCandle(String line) {
        Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS);
        Matcher m=p.matcher(line);
        if(m.find())
            return new NewCandle(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9));
        else{
            GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line.");
            return new Newcandle(null,null,null,null,null,null,null,null,null);
        }
    }
}

--
"Either help out or stop whining" - Evert

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

type568
Member #8,381
March 2007
avatar

While we're on the topic of Java, does a call to another constructor using 'this' have to be first?

Yes, unfortunately it has to be the first line of a different overloaded constructor. Same as a call to super, if you wish to invoke the constructor of a parent class in a constructor of inheriting class. Now if you can invoke both(since one will be a second line) I'm not sure, I think you can as long as only line before this() you have is a super().

@Elias
This is also a good idea, although of course the Factory should be an abstract, and the actual method should be a static.

I'll add a reply or edit this message after implementing it. Most likely will be tonight (@ GMT +3).

bamccaig
Member #7,536
July 2006
avatar

type568 said:
public NewCandle(String line){
Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS); Matcher m=p.matcher(line);
this=new NewCandle(null);

This would make no sense. If it was possible it would be infinitely recursive and overflow the stack! Not to mention, it wouldn't make sense for this to change mid-constructor.

type568
Member #8,381
March 2007
avatar

@bammcaig
I can't recognize this code, you sure it's mine?

Append: ah, yeah.. Didn't change it back. Was just to make sure such an assignment isn't possibre. The error there is that can't assign to a final value, which was what I wanted to check for which I needed some existing constructor with few arguments. :)

Append1:
I decided not to breed any new classes, it would also require wider functionality change. So I did this:

    public static NewCandle candleFromString(String line){
        Pattern p = Pattern.compile(P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_PRICE+" "+P_CHANGE+" "+P_UNS+" "+P_UNS+"."+P_UNS+"."+P_UNS);
        Matcher m=p.matcher(line);

        if(m.find())
            return new NewCandle(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5),m.group(6),m.group(7),m.group(8),m.group(9));
        else{
            GA.GA.reportError("DataManager.NewCandle.NewCandle: Failed to parse line.");
            return new NewCandle(null,null,null,null,null,null,null,null,null);
        }
    }

Generally instead of overloading the constructor, I made a passive method which returns a NewCandle by actually creating it with data parsed from the given line.

Go to: