Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
mrmcd
Feb 22, 2003

Pictured: The only good cop (a fictional one).

Jarl posted:

Anyone knows why it isn't possible to iterate over entries in a map in java without making and populating a set first (which is what getEntries does)? - Btw this is supported in the C++ standard library.

Short answer: Because Map doesn't implement Iterable.

Long answer: A map is, by definition, a mapping of keys to values. Iterable is designed for iterating over a orderable list of values of uniform type. In the context of a map the collections API doesn't make assumptions about if you want to iterate over the keys (.keySet()), values (.values()), or relationships (.entrySet()). I haven't looked, but I'm assuming that under the covers those methods return a shallow copy of the Map internals at worst, so it's not allocating a whole new copy of your data structure. This is also why ConcurrentModificationException is a thing.

Adbot
ADBOT LOVES YOU

Jarl
Nov 8, 2007

So what if I'm not for the ever offended?

mrmcd posted:

Short answer: Because Map doesn't implement Iterable.

Long answer: A map is, by definition, a mapping of keys to values. Iterable is designed for iterating over a orderable list of values of uniform type. In the context of a map the collections API doesn't make assumptions about if you want to iterate over the keys (.keySet()), values (.values()), or relationships (.entrySet()). I haven't looked, but I'm assuming that under the covers those methods return a shallow copy of the Map internals at worst, so it's not allocating a whole new copy of your data structure. This is also why ConcurrentModificationException is a thing.

Yes, it is shallow copy under the hood, but that doesn't change that it shouldn't be necessary (if it was only an option it was another matter). In C++ STL you can iterate over keys, values and entries too, so that's not the explanation. It's not important but I'm genuinely curious why this was decided.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Jarl posted:

Yes, it is shallow copy under the hood, but that doesn't change that it shouldn't be necessary (if it was only an option it was another matter). In C++ STL you can iterate over keys, values and entries too, so that's not the explanation. It's not important but I'm genuinely curious why this was decided.

I don't know, honestly I think iterating through a key set is more intuitive than iterating through the map and calling first() or second() or whatever on each element to get the value you want.

Java came later and worries a little more about protecting you from yourself than C++ does. C++ lets you overload operators, java says "hey pal just make em methods". Not a huge difference. You lose a little syntactic sugar but you gain readability.

Doctor w-rw-rw-
Jun 24, 2008

Jarl posted:

Yes, it is shallow copy under the hood, but that doesn't change that it shouldn't be necessary (if it was only an option it was another matter). In C++ STL you can iterate over keys, values and entries too, so that's not the explanation. It's not important but I'm genuinely curious why this was decided.

It's not even a shallow copy, it's a lazily-initialized facade (or view if you will) into the map.

Expecting Java, of all things, to try to inline things at compile time or paint over complexity with overloaded syntax (ref: mrmcd's explanation about iterators and sequential access) is kind of missing the point of, you know, Java.

I mean, jeez, the STL is the Standard Template Library. It is literally the standard library of undecidableness that waits until compile time to usually expand to logic that does what you expect. Just because the STL does something doesn't mean Java should do it too, or that the STL isn't masking essentially the same kind of thing.

And the objects Java creates for the iteration are so lightweight I'm sure Java does a pretty decent job of JITting it down to something small and reasonable at runtime. Map/HashMap are only some of the most used interfaces/implementations in the millions of Java programs out there.

Doctor w-rw-rw- fucked around with this message at 16:52 on Oct 23, 2013

Sedro
Dec 31, 2008

Jarl posted:

Yes, it is shallow copy under the hood, but that doesn't change that it shouldn't be necessary (if it was only an option it was another matter). In C++ STL you can iterate over keys, values and entries too, so that's not the explanation. It's not important but I'm genuinely curious why this was decided.
The sets are views over the map. This is specified by the map interface so an implementation using shallow copies would be broken.

They could have made Map<K,V> implement Iterable<Entry<K,V>>. I can't think of any downside.

mrmcd
Feb 22, 2003

Pictured: The only good cop (a fictional one).

If we want to talk about Java API design decisions we don't like, let's discuss why NumberFormatException is an unchecked exception. :colbert:

Doctor w-rw-rw-
Jun 24, 2008

Sedro posted:

The sets are views over the map. This is specified by the map interface so an implementation using shallow copies would be broken.

They could have made Map<K,V> implement Iterable<Entry<K,V>>. I can't think of any downside.

The fact that it would likely be implemented the same way anyways, only now iterable over a type it didn't directly contain doesn't strike you as bad API design? What if they wanted to change the implementation? What if you wanted to iterate twice over the same entry set and error if there was a concurrent modification in between iterations? Inlining the iteration syntax would recreate rather than reuse the entry set.

Sedro
Dec 31, 2008
It seems like an improvement to me. Look at any other language API; the map/dictionary/associative array will be iterable as key-value tuples.

Are you mixing up Iterable and Iterator? You can have two iterators going at the same time. There is only one entry set, so it would be functionally equivalent if it wasn't there. Just move its implementation into the map itself since they have the same lifetime.

Jarl
Nov 8, 2007

So what if I'm not for the ever offended?

Doctor w-rw-rw- posted:

It's not even a shallow copy, it's a lazily-initialized facade (or view if you will) into the map.

From reading the documentation here http://developer.android.com/reference/java/util/HashMap.html#keySet%28%29 I did not get the impression it was created lazily, as in it starts out empty and fills up as you iterate over it. Cool.

But yeah, what I really meant was that all references were copied, which they are (right?), albeit lazily.

Doctor w-rw-rw-
Jun 24, 2008

Jarl posted:

From reading the documentation here http://developer.android.com/reference/java/util/HashMap.html#keySet%28%29 I did not get the impression it was created lazily, as in it starts out empty and fills up as you iterate over it. Cool.

But yeah, what I really meant was that all references were copied, which they are (right?), albeit lazily.

No. Remember that a Set isn't an object, it's an interface, and the internal implementation for iterating over HashMap just crawls over the HashMap's own internal table. The facade itself isn't even created until it's used.

To spell it out:
- Zero memory impact when not used.
- Small and constant-size overhead when used.
- Reuses backing storage for iteration.

Jarl
Nov 8, 2007

So what if I'm not for the ever offended?

Doctor w-rw-rw- posted:

No. Remember that a Set isn't an object, it's an interface, and the internal implementation for iterating over HashMap just crawls over the HashMap's own internal table. The facade itself isn't even created until it's used.

To spell it out:
- Zero memory impact when not used.
- Small and constant-size overhead when used.
- Reuses backing storage for iteration.

Thanks.

Crumpet
Apr 22, 2008

Anyone got any clue why trying to bind to a port on a remote server (using a socket, obviously) would succeed when run as a standard java application, but fails when run under tomcat?

I've taken a look at network traffic both through my firewall and via wireshark, and I can see TCP requests heading out on the correct port and to the correct destination address, but all I end up with is a ConnectException under tomcat. This would be fine if it didn't work when not run under tomcat, and that I know the server is reachable under that port.

If it helps, I'm using OpenSMPP (here), and you can see how it's doing its binding here.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Crumpet posted:

Anyone got any clue why trying to bind to a port on a remote server (using a socket, obviously) would succeed when run as a standard java application, but fails when run under tomcat?

I've taken a look at network traffic both through my firewall and via wireshark, and I can see TCP requests heading out on the correct port and to the correct destination address, but all I end up with is a ConnectException under tomcat. This would be fine if it didn't work when not run under tomcat, and that I know the server is reachable under that port.

If it helps, I'm using OpenSMPP (here), and you can see how it's doing its binding here.

What do tomcat logs say? Are they receiving any requests? Is it actually running the application on tomcat?
Maybe a permissions issue, Tomcat might not even be running the program. Or it could be refusing the requests.

Check your tomcat configuration as well. Everything in /conf/, like server.xml and web.xml. I think you need to define a connector to the port you're using.

Crumpet
Apr 22, 2008

Zaphod42 posted:

What do tomcat logs say? Are they receiving any requests? Is it actually running the application on tomcat?
Maybe a permissions issue, Tomcat might not even be running the program. Or it could be refusing the requests.

Check your tomcat configuration as well. Everything in /conf/, like server.xml and web.xml. I think you need to define a connector to the port you're using.

Nothing in the tomcat logs other than the exceptions relating to this. Permissions are fine - I have full admin privileges on this machine, and I'm running tomcat from an elevated command prompt.

I've got a connector to the correct port in server.xml.

Defenestrategy
Oct 24, 2010


So I need to read in a text file, which has lines in format " name; category; cost; date;" take like categories and add the costs up and out put them as totaled.

I assume the best way to do this would be to take in each line as an array, compare the arrays at index 1 to a list of known categories and if they're alike add them up and store it as a float. Any help on how to do that or a better solution than what I got.

Java code:
import java.util.*;
import java.io.*;

public class lab7 
{
	
	public static void main(String[] args)
	{
		try
		{
			
              	  File file = new File("fileName");
		  FileReader fr = new FileReader(file); 
		  BufferedReader br = new BufferedReader(fr);
		  BufferedWriter wr = new BufferedWriter(new                FileWriter("fileName", true));
                  String newEntry;
                  Scanner scan = new Scanner( System.in )         
            
          //adds a new line
            System.out.println("Enter a new sale in the format of              name; category; sale; date; ");
            newEntry = scan.nextLine();
            wr.append( "\n" + newEntry ); 
            System.out.println("Done, thanks");
            
            //TODO: reads the text file, stores as an array, compares            //and adds
            		   
                    wr.flush();
		    wr.close();
		    br.close();
		    scan.close();
	    }
		catch(IOException e)
		{
			System.out.println("Didn't work!");
		}  

	}
}

Defenestrategy fucked around with this message at 20:25 on Oct 25, 2013

MrPablo
Mar 21, 2003

KildarX posted:

So I need to read in a text file, which has lines in format " name; category; cost; date;" take like categories and add the costs up and out put them as totaled.

I assume the best way to do this would be to take in each line as an array, compare the arrays at index 1 to a list of known categories and if they're alike add them up and store it as a float. Any help on how to do that or a better solution than what I got.

Java code:
import java.util.*;
import java.io.*;

public class lab7 
{
	
	public static void main(String[] args)
	{
		try
		{
			
              	  File file = new File("fileName");
		  FileReader fr = new FileReader(file); 
		  BufferedReader br = new BufferedReader(fr);
		  BufferedWriter wr = new BufferedWriter(new                FileWriter("fileName", true));
                  String newEntry;
                  Scanner scan = new Scanner( System.in )         
            
          //adds a new line
            System.out.println("Enter a new sale in the format of              name; category; sale; date; ");
            newEntry = scan.nextLine();
            wr.append( "\n" + newEntry ); 
            System.out.println("Done, thanks");
            
            //TODO: reads the text file, stores as an array, compares            //and adds
            		   
                    wr.flush();
		    wr.close();
		    br.close();
		    scan.close();
	    }
		catch(IOException e)
		{
			System.out.println("Didn't work!");
		}  

	}
}

One way to handle this is to split each input line on ";", use the second and third columns to populate a map of categories to sums, then print the result. Here's an example:

code:
 
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Map;
import java.util.HashMap;

public final class Foo {
  private static final Map<String,Double> sums = new HashMap<String,Double>();

  public static void main(final String args[]) throws Exception {
    if (args.length != 1)
      throw new Exception("missing input file");

    // read command-line arguments
    read(args[0]);

    // print results
    print();
  }

  private static void read(final String path) throws Exception {
    final BufferedReader in = new BufferedReader(new FileReader(path));
    String line;

    // walk over arguments and parse each one
    while ((line = in.readLine()) != null) {
      // split argument into columns
      final String cols[] = line.split(";");

      // check for error
      if (cols.length != 4)
        throw new Exception("bad line: " + line);

      // add value to map
      add(cols[1], Double.parseDouble(cols[2]));
    }
  }

  private static void print() {
    // print results to screen
    for (String cat: sums.keySet())
      System.out.println(String.format("%s: %f", cat, sums.get(cat)));
  }

  private static void add(final String cat, double val) {
    // add existing sum from category map
    if (sums.containsKey(cat))
      val += sums.get(cat);

    // save value to map
    sums.put(cat, val);
  }
};
Which produces results like so:

code:
> cat test.txt
bob;cat 1;10;date
frank;cat 1;5.2;date
joe;cat 2;100;date
bill;cat 2;20;date
> java Foo test.txt
cat 2: 120.000000
cat 1: 15.200000

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.

KildarX posted:

So I need to read in a text file, which has lines in format " name; category; cost; date;" take like categories and add the costs up and out put them as totaled.

I assume the best way to do this would be to take in each line as an array, compare the arrays at index 1 to a list of known categories and if they're alike add them up and store it as a float. Any help on how to do that or a better solution than what I got.

Personally, I'd read in each line as a String, and use String.split() to split the input on the semicolon. I'd then use a Map<String, Float> to associate each category with it's sum of costs.

@MrPablo: Since this is titled "lab 7", you should give hints, but probably avoid flat-out doing this guy's homework for him. :(

MrPablo
Mar 21, 2003

Gravity Pike posted:

@MrPablo: Since this is titled "lab 7", you should give hints, but probably avoid flat-out doing this guy's homework for him. :(

Yeah, that occurred to me a few minutes ago as well. :(

Defenestrategy
Oct 24, 2010

Gravity Pike posted:

Personally, I'd read in each line as a String, and use String.split() to split the input on the semicolon. I'd then use a Map<String, Float> to associate each category with it's sum of costs.

@MrPablo: Since this is titled "lab 7", you should give hints, but probably avoid flat-out doing this guy's homework for him. :(

:sigh: I guess I'm over thinking it again, thought I was gonna be clever using arrays and crap.

Thanks for the help guys, back to drawing board.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Crumpet posted:

Nothing in the tomcat logs other than the exceptions relating to this. Permissions are fine - I have full admin privileges on this machine, and I'm running tomcat from an elevated command prompt.

I've got a connector to the correct port in server.xml.

Oh, I see, Tomcat is trying to connect to the remote server, I figured that you were running the server on tomcat, rather than as an application.

Hmm, so Tomcat is the client. What about the server then, do you have access to its logs?

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.

KildarX posted:

:sigh: I guess I'm over thinking it again, thought I was gonna be clever using arrays and crap.

Thanks for the help guys, back to drawing board.

So other people might fervently disagree with me on this statement, but, as a professional software developer: Never be clever.

There are many things that you can optimize for in your code: speed, memory usage, source lines, compile size. The most important is maintainability. If you think you're being clever, the person sitting next to you is going to read the code and think that it's confusing. Clever code causes bugs. Clever code eats up dev-hours as people try to parse through your logic. Clever code usually fails to foresee the product requirement that is going to be thrown at the codebase a few months down the line. Clever code takes somewhere between two and ten times as long to update as boring, idiomatic code.

By all means, be intelligent. Write smart code. But remember that your code is going to be read by other devs far more frequently that the one time that you write it. It not only has to produce the correct output, it has to, at a glance, look like it's going to produce the correct output.

Crumpet
Apr 22, 2008

Zaphod42 posted:

Oh, I see, Tomcat is trying to connect to the remote server, I figured that you were running the server on tomcat, rather than as an application.

Hmm, so Tomcat is the client. What about the server then, do you have access to its logs?

Sadly, I do not - the server in question is a staging server which is part of a department that's only related to mine by name. I suppose I could submit a request for logs, but they'd take about 2 weeks to materialise. Thankfully this is only a POC, so I'm in no particular rush to get this sorted - and I always have the option of just not using tomcat.

Volguus
Mar 3, 2009

Gravity Pike posted:

So other people might fervently disagree with me on this statement, but, as a professional software developer: Never be clever.

There are many things that you can optimize for in your code: speed, memory usage, source lines, compile size. The most important is maintainability. If you think you're being clever, the person sitting next to you is going to read the code and think that it's confusing. Clever code causes bugs. Clever code eats up dev-hours as people try to parse through your logic. Clever code usually fails to foresee the product requirement that is going to be thrown at the codebase a few months down the line. Clever code takes somewhere between two and ten times as long to update as boring, idiomatic code.

By all means, be intelligent. Write smart code. But remember that your code is going to be read by other devs far more frequently that the one time that you write it. It not only has to produce the correct output, it has to, at a glance, look like it's going to produce the correct output.

To add to this, a very wise man once said:

quote:

Write code as if the person who's going to maintain it is a violent psychopath who knows where you live.

Code quality measurement comic: http://www.techtoolblog.com/archives/wtfminute-code-reviews

Volguus
Mar 3, 2009

Crumpet posted:

Sadly, I do not - the server in question is a staging server which is part of a department that's only related to mine by name. I suppose I could submit a request for logs, but they'd take about 2 weeks to materialise. Thankfully this is only a POC, so I'm in no particular rush to get this sorted - and I always have the option of just not using tomcat.

There should (in theory) be no reason why you are able to connect to a remote server when running as a standalone application but not when running as a web application in an application server.

I see that you have ensured that the user tomcat runs under is a privileged one, but just double/triple check. Who knows?
Is it under Windows? Maybe the java process that runs tomcat is different from the java process that runs your standalone application (I have a ton of jdk's installed and it's easy to choose a "wrong" one) and Windows firewall may be blocking that one but not yours?

That's all i can think of right now, but this should not happen. At all. It doesn't really make any sense. As a last resort, make the simplest, dumbest web app, that only has one index.jsp that makes a connection to that server and see if it works or not.

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!
A lot of times, things like Tomcat run with elevated privileges, then drop them when they're done with certain things (e.g., binding ports below 1024 on Linux).

FAT32 SHAMER
Aug 16, 2012



Okay, so I've been trying to wrap my head around inheritance (and honestly, OOP in general since it sounds great in principle but the implementation of it can be confusing to me) and I'm having a little bit of a stumble here with my test class.

To give you guys some context, here's the assignment:
code:
/* Write an inheritance hierarchy for classes Quadrilateral, Trapezoid,
 * Parallelogram, Rectangle, and Square. Use Quadrilateral as the Superclass of
 * the heirarchy as deep (ie many levels) as possible. Specify the instance vars
 * for each class. The private instance vars of Quadrilateral should be the xy
 * coordinate pairs for the four endpoints of the quadrilateral. Write a programme
 * that instantiates objects of your classes and outputs each objects area
 * (except Quadrilateral's)
 */
Here's what I have so far

Java code:
package Quadrilateral;

public class locationPoints
{
    private double x, y;

    public locationPoints ( double xCoord, double yCoord )
    {
        x = xCoord;
        y = yCoord;
    }

    public double getX()
    {
        return x;
    }

    public double getY()
    {
        return y;
    }

    @Override
    public String toString()
    {
        return "( " + getX() + ", " + getY() + " )";
    }

}
package Quadrilateral;

public class Quadrilateral extends Object
{
    locationPoints point1, point2, point3, point4;

    public Quadrilateral( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4)
    {
        point1 = new locationPoints( x1, y1 );
        point2 = new locationPoints( x2, y2 );
        point3 = new locationPoints( x3, y3 );
        point4 = new locationPoints( x4, y4 );
    }

    public locationPoints getPoint1()
    {
        return point1;
    }

    public locationPoints getPoint2()
    {
        return point2;
    }

    public locationPoints getPoint3()
    {
        return point3;
    }

    public locationPoints getPoint4()
    {
        return point4;
    }

    @Override
    public String toString()
    {
        return "The Coordinates of this quadrilateral are: \n"
                + printCoords();
    }

    public String printCoords()
    {
        return point1.toString() + ", " + point2.toString() + ", " +
                point3.toString() + ", " + point4.toString();
    }

    
 }
package Quadrilateral;

import Quadrilateral.Quadrilateral;


public class Trapezoid extends Quadrilateral
{
    double height;

    public Trapezoid( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4 )
    {
        super ( x1, y1, x2, y2, x3, y3, x4, y4 );
    }

    public double getHeight()
    {
        if ( getPoint1().getY() == getPoint2().getY() )
            return Math.abs( getPoint2().getY() - getPoint2().getY() );
        else
            return Math.abs( getPoint1().getY() - getPoint2().getY() );
    }

    public double getArea()
    {
        return getSumOfLengths() * getHeight() / 2;
    }

    public double getSumOfLengths()
    {
        if ( getPoint1().getY() == getPoint2().getY() )
            return Math.abs( getPoint1().getX() - getPoint2().getX() ) +
                    Math.abs( getPoint3().getX() - getPoint4().getX() );
        else
            return Math.abs( getPoint2().getX() - getPoint3().getX() ) +
                    Math.abs( getPoint4().getX() - getPoint1().getX() );
    }

    @Override
    public String toString()
    {
        return "\nThe Coordinates of the Trapezoid are: \n" + printCoords() +
                "\nThe Height is: " + getHeight() + "\nThe Area is: " + getArea();

    }

}
package Quadrilateral;

import Quadrilateral.Quadrilateral;
public class Rectangle extends Quadrilateral
{
    double length;
    double width;

    public Rectangle( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4 )
    {
        super( x1, y1, x2, y2, x3, y3, x4, y4 );
    }

    public double getWidth()
    {
        if ( getPoint1().getY() == getPoint2().getY() )
            return Math.abs( getPoint2().getY() - getPoint2().getY() );
        else
            return Math.abs( getPoint1().getY() - getPoint2().getY() );
    }

    public double getSumOfLengths()
    {
        if ( getPoint1().getY() == getPoint2().getY() )
            return Math.abs( getPoint1().getX() - getPoint2().getX() ) +
                    Math.abs( getPoint3().getX() - getPoint4().getX() );
        else
            return Math.abs( getPoint2().getX() - getPoint3().getX() ) +
                    Math.abs( getPoint4().getX() - getPoint1().getX() );
    }

    public double getArea()
    {
        return getSumOfLengths() * getWidth();
    }

    @Override
    public String toString()
    {
        return "\nThe Coordinates of the Rectangle are: \n" + printCoords() +
                "\nThe Height is: " + getWidth() + "\nThe Length is:  "
                + getSumOfLengths()/2 + "\nThe Area is: " + getArea();
    }

}

package Quadrilateral;

import Quadrilateral.Rectangle;

public class Square extends Rectangle
{
    double side;

    public Square( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4 )
    {
        super ( x1, y1, x2, y2, x3, y3, x4, y4 );

    }

    public double getSide()
    {

    }

}


Now, granted the classes aren't all done yet, but in my test class, I'm getting an odd error

Java code:
package Quadrilateral;

import Quadrilateral.Quadrilateral;
import Quadrilateral.Parallelogram;
import Quadrilateral.Rectangle;
import Quadrilateral.Square;
import Quadrilateral.Trapezoid;
import Quadrilateral.locationPoints;

public class QuadrilateralTest
{
    public static void main(String[] args)
    {
        Quadrilateral quadrilateral = new Quadrilateral( new locationPoints( 1.1, 1.2 ),
                new locationPoints( 6.6, 2.8 ), new locationPoints( 6.2, 9.9 ),
                new locationPoints( 2.2, 7.4 ));
        Trapezoid trapezoid = new Trapezoid( new locationPoints( 0.0, 0.0 ),
             new locationPoints( 10.0, 0.0 ), new locationPoints( 8.0, 5.0 ),
             new locationPoints( 3.3, 5.0 ) );

        Parallelogram parallelogram = new Parallelogram( new locationPoints( 5.0, 5.0 ),
                new locationPoints( 11.0, 5.0 ), new locationPoints( 12.0, 20.0 ),
                new locationPoints( 6.0, 20.0 ));

        Rectangle rectangle = new Rectangle( new locationPoints( 17.0, 14.0 ),
                new locationPoints( 30.0, 14.0 ), new locationPoints( 30.0, 28.0 ),
                new locationPoints( 17.0, 28.0 ) );

        Square square = new Square( new locationPoints( 4.0, 4.0 ),
                new locationPoints( 8.0, 0.0 ), new locationPoints( 8.0, 4.0 ),
                new locationPoints( 4.0, 4.0 ) );

        System.out.printf( "%s %s %s %s %s\n",
                quadrilateral, trapezoid, parallelogram, rectangle, square );

    }
}

quote:

cannot find symbol
symbol: constructor Quadrilateral(Quadrilateral.locationPoints,Quadrilateral.locationPoints,Quadrilateral.locationPoints,Quadrilateral.locationPoints)
location: class Quadrilateral.Quadrilateral
at Quadrilateral.QuadrilateralTest.main(QuadrilateralTest.java:14)

A few questions about this giant wall o' code:
1) Do I make class Quadrilateral extends Object or am I misunderstanding something?

2) if I make class Square extend Rectangle then use super( x1, y1, ... , x4, y4 ) will that be inheriting those variables from class Quadrilateral or from class Rectangle? I'm assuming it'd be from Rectangle and ultimately Quadrilateral but I just wanted to double check.

3) How do I go about fixing the error in the test class? I explicitly defined the constructors in their classes (or at least as far as I understand, I did :shobon:), so if they're not inherited from their original classes, do I have to redefine them in class QuadrilateralTest

Thanks for reading through this massive post, this is one of the first things I've come across in Java that's legitimately stumped me. Otherwise, I've really enjoyed it, especially compared to C/C++.

FAT32 SHAMER fucked around with this message at 22:48 on Oct 27, 2013

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Tusen Takk posted:

1) Do I make class Quadrilateral extends Object or am I misunderstanding something?

All classes implicitly extend Object if no extends is specified, meaning all classes are a subclass of object, even if they may be a distant descendant.

Tusen Takk posted:

2) if I make class Square extend Rectangle then use super( x1, y1, ... , x4, y4 ) will that be inheriting those variables from class Quadrilateral or from class Rectangle? I'm assuming it'd be from Rectangle and ultimately Quadrilateral but I just wanted to double check.

Instance variables with the same name are overridden by subclasses, which means that for any variable that exists in several classes that are in the same inheritance hierarchy, the lowest one is used. The same goes for methods. In this case, because Rectangle has a constructor accepting the same number of arguments of the same type in the same order, you will use Rectangle's constructor. However, if Rectangle's constructor did not take exactly 8 doubles, but you called the 8 double super(), it would use Quadrilateral's constructor directly.

Tusen Takk posted:

3) How do I go about fixing the error in the test class? I explicitly defined the constructors in their classes (or at least as far as I understand, I did ), so if they're not inherited from their original classes, do I have to redefine them in class QuadrilateralTest

Quadrilateral and all subclasses have a constructor taking 8 double variables. You are trying to call it and supply 4 locationPoint variables. Java has no way of knowing how to convert the two, so you should specify the points as doubles and let the constructor make the locationPoints objects. Your other option is to create another constructor which takes four locationPoints variables and just store them in the instance variables; this is called overloading.

carry on then fucked around with this message at 22:03 on Oct 27, 2013

FAT32 SHAMER
Aug 16, 2012



carry on then posted:

All classes implicitly extend Object if no extends is specified, meaning all classes are a subclass of object, even if they may be a distant descendant.
Okay, that's what I assumed but assuming can make an "rear end out of u and me" :v:

quote:

Instance variables with the same name are overridden by subclasses, which means that for any variable that exists in several classes that are in the same inheritance hierarchy, the lowest one is used. The same goes for methods. In this case, because Rectangle has a constructor accepting the same number of arguments of the same type in the same order, you will use Rectangle's constructor. However, if Rectangle's constructor did not take exactly 8 doubles, but you called the 8 double super(), it would use Quadrilateral's constructor directly.
Perfect! This makes things much clearer :).

quote:

Quadrilateral and all subclasses have a constructor taking 8 double variables. You are trying to call it and supply 4 locationPoint variables. Java has no way of knowing how to convert the two, so you should specify the points as doubles and let the constructor make the locationPoints objects. Your other option is to create another constructor which takes four locationPoints variables and just store them in the instance variables; this is called overloading.
Okay, cool. So instead of
Java code:
Quadrilateral quadrilateral = new Quadrilateral( new locationPoints( 1.1, 1.2 ),
                new locationPoints( 6.6, 2.8 ), new locationPoints( 6.2, 9.9 ),
                new locationPoints( 2.2, 7.4 ));
I should have it do something more like
Java code:
Quadrilateral quadrilateral = new Quadrilateral( x1, y1 ), ... , new Quadrilateral( x4, y4 ); 
		//where (xn, yn) are the points from former variable locationPoints
?

I'm not really sure how I would go about creating a constructor to take the four locationPoints vars and store them in the instance vars though :shobon:.

edit:
actually, wouldn't it be
Java code:
Quadrilateral quadrilateral = new Quadrilateral( x1, y1, ..., x4, y4 );	

FAT32 SHAMER fucked around with this message at 22:47 on Oct 27, 2013

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

This is the signature of your Quadrilateral constructor:

Java code:
public Quadrilateral( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4)
It takes 8 different variables, all typed as double. That's what you need to supply in order to create a Quadrilateral.

As far as taking the four locationPoints vars instead of 8 doubles, look at the types of your instance variables and the types of the proposed arguments, and think about what (if anything) you need to do with the parameters to make the constructor have the same functionality as the one you already have.

FAT32 SHAMER
Aug 16, 2012



carry on then posted:

This is the signature of your Quadrilateral constructor:

Java code:
public Quadrilateral( double x1, double y1, double x2, double y2, double x3,
            double y3, double x4, double y4 ) )
It takes 8 different variables, all typed as double. That's what you need to supply in order to create a Quadrilateral.

As far as taking the four locationPoints vars instead of 8 doubles, look at the types of your instance variables and the types of the proposed arguments, and think about what (if anything) you need to do with the parameters to make the constructor have the same functionality as the one you already have.

OHHH okay so I have to either change the signature of Quadrilateral to something like

Java code:
public Quadrilateral( locationPoints( x1, y1 ), locationPoints( x2, y2 ), 
	locationPoints( x3, y3 ), locationPoints( x4, y4 )
or work with my original coding and feed in values for the variables like
Java code:
Quadrilateral quadrilateral = new Quadrilateral(  1.1, 1.2, 6.6, 2.8,
                6.2, 9.9, 2.2, 7.4 );
I think I get what you're driving at, thanks so much, mate!

edit: I got it working, now to just fix my logic errors and formatting!

output posted:

The Coordinates of this quadrilateral are:
( 1.1, 1.2 ), ( 6.6, 2.8 ), ( 6.2, 9.9 ), ( 2.2, 7.4 )
The Coordinates of the Trapezoid are:
( 0.0, 0.0 ), ( 10.0, 0.0 ), ( 8.0, 5.0 ), ( 3.3, 5.0 )
The Height is: 0.0
The Area is: 0.0 The Coordinates of this quadrilateral are:
( 5.0, 5.0 ), ( 11.0, 5.0 ), ( 12.0, 20.0 ), ( 6.0, 20.0 )
The Coordinates of the Rectangle are:
( 17.0, 14.0 ), ( 30.0, 14.0 ), ( 30.0, 28.0 ), ( 17.0, 28.0 )
The Height is: 0.0
The Length is: 6.5
The Area is: 0.0
The Coordinates of the Rectangle are:
( 4.0, 4.0 ), ( 8.0, 0.0 ), ( 8.0, 4.0 ), ( 4.0, 4.0 )
The Height is: 4.0
The Length is: 2.0
The Area is: 16.0

FAT32 SHAMER fucked around with this message at 23:01 on Oct 27, 2013

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Tusen Takk posted:

OHHH okay so I have to either change the signature of Quadrilateral to something like

Java code:
public Quadrilateral( locationPoints( x1, y1 ), locationPoints( x2, y2 ), 
	locationPoints( x3, y3 ), locationPoints( x4, y4 )

More like
Java code:
public Quadrilateral(locationPoints p1, locationPoints p2, locationPoints p3, locationPoints p4)
But as you have it working as is it's not a major concern.

Gravity Pike
Feb 8, 2009

I find this discussion incredibly bland and disinteresting.
You are kind of missing out on the major positive aspects of inheritance in your sample classes: abstract methods.

First off, inheritance means that you can stick a more-specific object in a less-specific variable:
Java code:
Quadrilateral q1 = new Square(); //a Square ALWAYS is-a Quadrilateral 
Square s1 = new Quadrilateral(); //compile-time error; a Quadrilateral MIGHT NOT BE a square.
With an abstract class, you're saying that everything that is this type of object will be able to implement a method, even if the method doesn't make sense on the abstract class itself.
Java code:

public abstract class Quadrilateral {
  public abstract Double getArea();
}

public class Rectangle extends Quadrilateral {
  //...
  @Override
  public Double getArea() {
    return getLength() * getHeight();
  }
}

public class Trapezoid extends Quadrilateral {
  //...
  public Double getArea() {
    return getSumOfLenghts() * getHeight() / 2;
  }
}
Note that since Quadrilateral is abstract, you can't instantiate it. It doesn't make sense for you to have something that's just a Quadrilateral; you wouldn't know what it looks like! Instead, you can have things that are different kinds of Quadrilaterals, and can all be used in similar ways.


Put these two concepts together, and you can do things like:
Java code:
// pretend these are initialized properly
Quadrilateral[] myShapes = {new Rectangle(), new Rectangle(), new Trapezoid(), new Square()};

int sumOfAreas = 0;
for (Quadrilateral q : myShapes) {
  sumOfAreas += q.getArea();
}

System.out.println("All of myShapes take up a combined area of: " + sumOfAreas);

FAT32 SHAMER
Aug 16, 2012



Gravity Pike posted:

You are kind of missing out on the major positive aspects of inheritance in your sample classes: abstract methods.

First off, inheritance means that you can stick a more-specific object in a less-specific variable:
Java code:
Quadrilateral q1 = new Square(); //a Square ALWAYS is-a Quadrilateral 
Square s1 = new Quadrilateral(); //compile-time error; a Quadrilateral MIGHT NOT BE a square.
With an abstract class, you're saying that everything that is this type of object will be able to implement a method, even if the method doesn't make sense on the abstract class itself.
Java code:

public abstract class Quadrilateral {
  public abstract Double getArea();
}

public class Rectangle extends Quadrilateral {
  //...
  @Override
  public Double getArea() {
    return getLength() * getHeight();
  }
}

public class Trapezoid extends Quadrilateral {
  //...
  public Double getArea() {
    return getSumOfLenghts() * getHeight() / 2;
  }
}
Note that since Quadrilateral is abstract, you can't instantiate it. It doesn't make sense for you to have something that's just a Quadrilateral; you wouldn't know what it looks like! Instead, you can have things that are different kinds of Quadrilaterals, and can all be used in similar ways.


Put these two concepts together, and you can do things like:
Java code:
// pretend these are initialized properly
Quadrilateral[] myShapes = {new Rectangle(), new Rectangle(), new Trapezoid(), new Square()};

int sumOfAreas = 0;
for (Quadrilateral q : myShapes) {
  sumOfAreas += q.getArea();
}

System.out.println("All of myShapes take up a combined area of: " + sumOfAreas);

That's pretty awesome, actually. I'm gonna have to go over my design and see if I can implement this and simplify what I have :3:. Thanks!!

Crumpet
Apr 22, 2008

Kilson posted:

A lot of times, things like Tomcat run with elevated privileges, then drop them when they're done with certain things (e.g., binding ports below 1024 on Linux).

This was exactly it, thanks.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Crumpet posted:

This was exactly it, thanks.

I knew it was permissions! :haw:

I've had so many cases where Tomcat doesn't start up properly when it should "just work", ugh.

Crumpet
Apr 22, 2008

Zaphod42 posted:

I knew it was permissions! :haw:

I've had so many cases where Tomcat doesn't start up properly when it should "just work", ugh.

Yeah, it didn't surprise me that it was permissions - there's really no other reason it shouldn't have worked fine.

And yes, most of my early dev time when creating some form of POC is struggling with tomcat, but this was a new one to my colleagues and I (admittedly, maven can sometimes be a hindrance rather than a help when battling tomcat, too).

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
I have a multiproject set up in Gradle. I'd like to be able to set a 'buildType' external property per subproject, so I can do some generic setup in the main build.gradle based on this 'buildType'. So for example, if a subproject has 'buildType' set to 'java', I would apply the java plugin, set up some default dependencies. If a subproject has 'buildType' set to 'javascript', I'd set up npm tasks, whatever.

Anyway, I'm having trouble setting this up. For some reason Gradle doesn't allow me to filter subprojects based on buildType, but that's probably because I'm doing something wrong :)

build.gradle:
code:
def javaModules() {
    subprojects.findAll { project -> project.buildType == "java" }
}

def javascriptModules() {
    subprojects.findAll { project -> project.buildType == "javascript" }
}

configure(javaModules) { /* stuff */ }
configure(javascriptModules) { /* stuff */ }
settings.gradle:
code:
include 'sub1'
include 'sub2'
include 'sub3'
sub1/build.gradle:
code:
ext { buildType = "java" }
sub2/build.gradle:
code:
ext { buildType = "javascript" }
sub3/build.gradle:
code:
ext { buildType = "java" }

ahmeni
May 1, 2005

It's one continuous form where hardware and software function in perfect unison, creating a new generation of iPhone that's better by any measure.
Grimey Drawer
We've recently started having trouble with some Java based projects at work (Jive, if anyone is familiar) that have started hitting their heap limit of 4GB. We've increased to 6GB and it seems to have stabilized but we have a lot of concerns that something is deeply hosed up with the code.

Are heap dumps with tools like jmap very useful from our operations non-developer perspective? Are heap/stack dumps possible without completely pegging the system in a production environment?

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

ahmeni posted:

We've recently started having trouble with some Java based projects at work (Jive, if anyone is familiar) that have started hitting their heap limit of 4GB. We've increased to 6GB and it seems to have stabilized but we have a lot of concerns that something is deeply hosed up with the code.

Are heap dumps with tools like jmap very useful from our operations non-developer perspective? Are heap/stack dumps possible without completely pegging the system in a production environment?

Heap dumps won't be too useful to your ops people, there's rarely anything they can adjust if it's a problem with the application. However it will be useful for devs to figure out where the problem is and have a good starting place to fix it.

There is a JVM option to save a heap dump in case an OutOfMemoryError occurs
pre:
-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath=/disk2/dumps
I don't know if you can otherwise get a dump without pegging the system. You might try poking around this tool: Eclipse MAT to see if has any other ways of generating a dump. I would still recommend using it, since the normal JVM tools will barf on heaps that large. Just make sure you have a lot of memory, I had to spin up an Amazon XLargeMem just analyze the dump!

Adbot
ADBOT LOVES YOU

Azerban
Oct 28, 2003



Gravity Pike posted:

So other people might fervently disagree with me on this statement, but, as a professional software developer: Never be clever.

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply