With Statement in Java

WITH statement in Java

No. The best you can do, when the expression is overly long, is to assign it to a local variable with a short name, and use {...} to create a scope:

{
TypeOfFoo it = foo; // foo could be any lengthy expression
it.bar();
it.reset(true);
myvar = it.getName();
}

Is there a Java equivalent to Javascript's with statement?

If the class of obj is under your control, you could provide a Fluent interface, basically returning this in every function. This would let you chain method calls like this-

obj.getHomeworkAverage().getTestAverage().getAttendance();

Java equivalent to python's with

As Mohammed noted, you can use try-with-resources. In this case, you want to have your own resource, and it is not really difficult to do.

Creating an auto-closeable class

First, your class should implement AutoCloseable:

public class CaptureOutput implements AutoCloseable {

When constructing this class, you should

  • store the old System.out,
  • create a PrintStream to replace it (cf. Java: PrintStream to String?) and
  • replace the default stream with System.setOut().

Here is how we do it

    public CaptureOutput() {
this.stream = new ByteArrayOutputStream();
this.out = System.out;

System.setOut(new PrintStream(stream));
}

The secret is the AutoCloseable.close() method: you just undo your replacement there:

    public void close() throws Exception {
System.setOut(this.out);
}

Finally, you need a method to retrieve the content:

    public String getContent() {
return this.stream.toString();
}

Using try-with-resources

Done that, just pass the CaptureOutput to the try clause. The code below, for example...

public static void main(String[] args) throws Exception {
String content = null;

System.out.println("This will be printed");

try (CaptureOutput co = new CaptureOutput()) {
System.out.println("EXAMPLE");

content = co.getContent();
}

System.out.println("This will be printed, too.");

System.out.println("The content of the string is " + content);
}

...will result on this:

This will be printed
This will be printed, too.
The content of the string is EXAMPLE

Scope issues

Note that we do not call co.getContent() at the last line. It is not possible because, unlike Python, the co variable is scoped inside the try clause. Once the try block finishes, it is gone.[1] That's why we get the value from inside the block.

Not that elegant, right? A solution may be to give the BAOS to the CaptureOutput constructor:

    public CaptureOutput(ByteArrayOutputStream stream) {
this.stream = stream;
this.out = System.out;

System.setOut(new PrintStream(this.stream));
}

Now, we just use the stream later:

    public static void main(String[] args) throws Exception {
System.out.println("This will be printed");

ByteArrayOutputStream stream = new ByteArrayOutputStream();

try (CaptureOutput co = new CaptureOutput(stream)) {
System.out.println("EXAMPLE");
}

System.out.println("This will be printed, too.");

System.out.println("The content of the string is " + stream.toString());
}

(Also, it is not possible to create the CaptureOutput variable before the try. That makes sense: AutoCloseable objects are supposed to be "closed" after their use. What's the use of a closed file, after all? Our use case is a bit different from that, so we have to rely on alternatives.)

The full classes

And here are the full classes:

  • CaptureOutput.java:

    import java.io.ByteArrayOutputStream;
    import java.io.PrintStream;

    public class CaptureOutput implements AutoCloseable {

    private ByteArrayOutputStream stream;
    private PrintStream out;

    public CaptureOutput(ByteArrayOutputStream stream) {
    this.stream = stream;
    this.out = System.out;

    System.setOut(new PrintStream(this.stream));
    }

    public CaptureOutput() {
    this(new ByteArrayOutputStream());
    }

    @Override
    public void close() throws Exception {
    System.setOut(this.out);
    }

    public String getContent() {
    return this.stream.toString();
    }

    }
  • Main.java:

    import java.io.ByteArrayOutputStream;

    public class Main {

    public static void main(String[] args) throws Exception {
    System.out.println("This will be printed");

    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    try (CaptureOutput co = new CaptureOutput(stream)) {
    System.out.println("EXAMPLE");
    }

    System.out.println("This will be printed, too.");

    System.out.println("The content of the string is " + stream.toString());
    }

    }

Having problem with solving a problem regarding Statements and Expressions in Java(The statement x = y = x = 0 is illegal??)

a

Take the expression a+1 for instance. This makes no sense as a statement as it does not change anything and is not possible.

b

x++ returns x and increments it afterwards.

As it changes the variable, it can be used as a statement.

c

When you assign a value to something else, it returns the assigned value.

d

This is possible because x=0 sets x to 0 and returns 0.

Then, it sets y to x (0) and returns this value (0).

Then, it sets x to y (0) (and returns this value (0)).

Does Java have a IN operator or function like SQL?

There are many collections that will let you do something similar to that. For example:

With Strings:

String s = "I can has cheezeburger?";
boolean hasCheese = s.contains("cheeze");

or with Collections:

List<String> listOfStrings = new ArrayList<String>();
boolean hasString = listOfStrings.contains(something);

However, there is no similar construct for a simple String[].

Simulating python's With statement in java

Not at the moment; Java still hasn't added syntactic sugar for this pattern. Still, it won't get as clean as with(Python) or using(C#), but you can at least clean that up a little bit by just having one call to c.close() inside a finally block, instead of twice as you've done:

try {
// use c
} finally {
c.close()
}

This also brings it in line with how both with and using are actually implemented, which is a try..finally block (not a try..catch).

JDBC Statement.closeOnCompletion() should close statement on next execution?

With calling closeOnCompletion() you signal that you want the statement to close after you've closed its last result set (which 'completes' the execution), so the statement will close itself once execution completes. For non-result-set producing statements, it has no effect (you should call close() yourself). For result-set-producing statements, execution completes once you close the last result set. The primary use-case for this is when you return a result set for processing, but don't want to keep track of its statement.

Given another execution on the same statement will close any open result set from that statement, having enabled closeOnCompletion, will automatically close the statement as a result.

It would be a user error to signal closeOnCompletion, but then continue to use the statement anyway by executing another statement, so raising a SQLException is appropriate.

As an aside, the text

However, a call to closeOnCompletion does effect both the subsequent
execution of statements, and statements that currently have open,
dependent, result sets.

means that if you call closeOnCompletion it will affect the next execution that produces a result set, or if you currently have a result set open, the current execution.

This is also supported by the replies in the discussion on jdbc-spec-discuss mailing list by Lance Andersen (JDBC specification leader) and Douglas Surber (JSR-221 JDBC Expert Group member on behalf of Oracle), specifically:

The overall intent was to deal with code similar to:

ResultSet rs = foo();
while(rs.next() {
/*do something */
}
rs.close();

public ResultSet foo() {

Statement stmt = con.createStatement();
stmt.closeOnCompletion();
ResultSet rs = stmt.executeQuery(aQuery);
return rs
}

We did spend a lot of time on this back in 2009 and took quite a bit
of time to reach agreement on the current wording. However, it does
look like there is the potential for some additional word smithing.

(Lance Andersen, https://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/2021-February/000542.html)



I wrote the original proposal. The intent was to handle the case Lance
described. It was not intended to allow multiple executions of the
Statement. So while the language may not be as clear as it needs to
be, the case Filipe described should throw on the second execution of
the Statement. At least that was my intent.

(Douglas Surber, https://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/2021-February/000543.html)



As Douglas points out at the time of the discussion, the JDBC EG
consensus was the Statement would be closed. If applications did not
want this behavior they should not call Statement::closeOnCompletion
and if they were not sure if the method had been invoked, they could
always call Statement::isCloseOnCompletion to make a decision
programatically.

This area as you are aware is messy enough and the intent was to
address a common use case which lead to common issues for applications
and not further complicate things.

(Lance Andersen, https://mail.openjdk.java.net/pipermail/jdbc-spec-discuss/2021-February/000548.html)



return statement in Java use

  1. When detecting prime numbers, the statement if (c * c > n) is redundant because this line is reached only when while (c * c <= n) loop has completed, that is, this condition is already verified in the while:
public static boolean prime(int n) {
if (n <= 1) {
return false;
}
int c = 2;
while (c * c <= n) {
if (n % c == 0) {
return false;
}
c++;
}
return true;
}

  1. When detecting a palindrome, instead of if-else statement returning a boolean, a cleaner form should be used to return the result of the comparison:
public static boolean palindrome(int n) {
int copy = n;
int add = 0;
int rem = 0;
while (n > 0) {
rem = n % 10;
add = add * 10 + rem;
n = n / 10;
}
return add == copy;
}

How to use a prepared sql statement in a global DbConnection in java?

As suggested in some comments, your method breaks the Java security guidelines, for a number of reasons, most important ones:

  • It doesn't perform and check against the input
  • It is a wide open door to SQL injection attack, as it does not control which type of query is performed over the database.

However, if this is just a school work, I can help you with implementing that by using PreparedStatemnt.

The idea is that you make the assumption that the invoker knows the number of parameters included in the input query and gives the exact number of values for it.

Based on that, the easiest implementation I can think of is the following one:

public ArrayList<Map<String, Object>> performGenericParameterizedQuery(String queryWithParameters, 
Object ... values) {

ArrayList<Map<String, Object>> result = new ArrayList<>();

try(PreparedStatement ps = this.connection.preparedStatement(queryWithParameters)) {

for(int i=0; i<values.length; i++) {
ps.setObject(i+1, values[i]);
}

ResultSet rs = ps.executeQuery();

ResultSetMetaData metaData = rs.getMetaData();

while (rs.next()){

Map<String, Object> row = new HashMap<>();

for (int i = 1; i <= metaData.getColumnCount(); i++){
String strColumnName = metaData.getColumnName(i);
Object columnValue = rs.getObject(i);
row.put(columnValue, strColumnName);
}
result.add(row);
}

}catch (SQLException e){
e.printStackTrace();
}

return result;
}

To be honest, I haven't actually compiled or tested that method. but I just wanted to give you the idea of how to "generically" use the PreparedStatement. I assumed you have the connection instance available in your class (you may have it as Singleton or just prepare in a specific init method of your class), plus you should add all the required import.

You can notice that I used a List of Map, instead of the structure you had choosen, which in my opinion is clearer and more appropriated for the purpose.

In addition, as I did, I would always suggest to wrap your statement on a try-with-resource block, so it will automatically gets closed (along with the ResultSet) once the execution goes out from the block and there is not going to be any resource leak.



Related Topics



Leave a reply



Submit