C# code passing void as argument? What's that in Java? [duplicate] - java

This question already has answers here:
C# Lambda ( => ) [duplicate]
(4 answers)
Closed 6 years ago.
I'm translating a small program from C# to Java.
There's 1 line left that I'm wondering about:
Thread eventReadingThread = new Thread(() => ReadEvents(url, streamingMode));
...
static void ReadEvents(String serviceURL, bool streamingMode)
{
if (streamingMode)
{
WebRequest httpClient = WebRequest.Create(serviceURL);
httpClient.Method = "GET";
byte[] buffer = new byte[4096];
...
I interpret the first line here as "True if ReadEvents returns less than empty array". However it doesn't make any sense, both because void arguments don't compile and because a boolean argument doesn't fit the constructor for Thread.
What would this be in Java?

What would it be in Java?
In Java 8 you just turn => to ->.
{
Thread thread = new Thread(() -> readEvents(url, streamingMode));
}
static void readEvents(String serviceUrl, boolean streamingMode) {
// ...
}
I interpret the first line here as .... What is the code trying to do?
You need to read up on lambda expressions (Java, C#). In this case it is "create me a Runnable or ThreadStart that calls the method readEvents.

First,
static void ReadEvents
does not mean ReadEvents returns true under any circumstances. The void keyword means that the method has no return (like a Sub in VB).
Second, you define your array as:
byte[] buffer = new byte[4096];
The default value for byte is 0, so you never actually have an empty array, you instead, have an array of 4096 bytes with the value 0. Unless somewhere further in the code (which you are not showing) you redefine the array as byte[] or null.

Related

Java 8 variable should be final or effectively final issue [duplicate]

This question already has answers here:
Variable used in lambda expression should be final or effectively final
(9 answers)
Closed 1 year ago.
I am using Java 8 stream Iteration with a variable that should be used in other classes also. So I have used the below code.
AtomicBoolean bool = new AtomicBoolean(true);
public void testBool(){
list.stream().forEach(c->{
if( c.getName() != null){
bool.set(true);
}
});
}
public void test(){
if(bool.get()){
System.out.println("value is there");
}
}
But I heard like using the Atomic Object will be a performance hit sometimes. Is there any alternate approach to use the variables outside the forEach block with Java 8 usage?
Without this am getting the error as a variable should be a final or effectively final error.
Please help me to resolve this issue.
Thanks in advance.
You could avoid the problem by using the lambda expression to return true or false if there are any names that are not null, and assign the result to your boolean.
Something like this:
boolean hasAnyWithNames = list.stream().anyMatch(c -> c.getName() != null);
The choice "bool" is not a good one for variable name by the way.
Edit:
Replaced Boolean with base type per comment.
Used anyMatch() instead of filter() count per comment
Thanks
The effectively final restriction only applies to local variables.
Since you are setting an instance field, you can simply use:
boolean bool = true; and set it from within the lambda.
If you need to use a local variable, add the final modifier to the declaration.
Regarding the overhead of using AtomicBoolean, keep in mind that streams also have overhead and if you're only using them for iteration you're better off using a for loop instead:
boolean bool = true;
public void testBool(){
for (var c : list) {
if (c.getName() != null) {
bool = true;
break;
}
}
}
Lastly, as #Neela mentioned in a comment, a more efficient use of streams would be with the following code*:
boolean bool = list.stream().anyMatch(c -> c.getName() != null);
*Note, the original code has an error that results in bool always being true and this is avoided by not presetting true and directly putting the result of anyMatch.

java.lang.UnsupportedOperationException at java.nio.ByteBuffer.array(ByteBuffer.java:959)

The following Java code compiles, but there's an error at runtime:
# javac ByteBufTest.java
# java ByteBufTest
Exception in thread "main" java.lang.UnsupportedOperationException
at java.nio.ByteBuffer.array(ByteBuffer.java:959)
at ByteBufTest.<init>(ByteBufTest.java:12)
at ByteBufTest.main(ByteBufTest.java:33)
#
Why does this happen?
Note:Next, I need to use mDirectBuffer in JNI, so I have to use the ByteBuffer.allocateDirect(TEST_BUFFER_SIZE) function。
ByteBufTest.java:
import java.nio.ByteBuffer;
public class ByteBufTest {
public static final int TEST_BUFFER_SIZE = 128;
private ByteBuffer mDirectBuffer;
public ByteBufTest() {
mDirectBuffer = ByteBuffer.allocateDirect(TEST_BUFFER_SIZE);
byte[] buf = mDirectBuffer.array();
buf[1]=100;
}
public void test() {
printBuffer("nativeInitDirectBuffer",mDirectBuffer.array());
}
private void printBuffer( String tag, byte[] buffer ) {
StringBuffer sBuffer = new StringBuffer();
for( int i=0; i<buffer.length; i++ ) {
sBuffer.append(buffer[i]);
sBuffer.append(" ");
}
//System.out.println(tag+sBuffer);
}
public static void main(String[] args) throws Exception {
ByteBufTest item = new ByteBufTest();
item.test();
}
}
This is the expected behaviour. The Javadoc states
throws UnsupportedOperationException - If this buffer is not backed by an accessible array
You should try another approach or search for another implementation, e.g.
mDirectBuffer = ByteBuffer.wrap(new byte[TEST_BUFFER_SIZE]);
This exception occurs at runtime if the resulting buffer is not backed by an accessible array. You can try allocate() method.
You should call java.nio.ByteBuffer.hasArray() to ensure that java.nio.ByteBuffer.array() will succeed in order to write clean and portable code as stated in the Java API documentation:
If this method returns true then the array and arrayOffset methods may safely be invoked
You can allocate a direct writable NIO byte buffer in your Java source code by calling java.nio.ByteBuffer.allocateDirect(int) as you already do and call java.nio.ByteBuffer.get(byte[]) to store the content of the buffer into an array, this method is supported by Android too. Keep in mind that it's a relative operation that affects the position of the NIO buffer.
Maybe another approach would consist in using the NIO buffer as is without doing any conversion but I'm not sure that it suits your needs.

Don't get compilation error when using three dots notation for parameters [duplicate]

This question already has answers here:
What do 3 dots next to a parameter type mean in Java?
(9 answers)
Closed 6 years ago.
I want to generate CSV files. I have a generateCSV method which takes a filename as parameters and a bunch of entries
private static void generateCSV(String pFilename, String... pColumns) {
try(FileWriter fileWriter = new FileWriter(pFilename,true)) {
for(String column : pColumns) {
fileWriter.append(column);
fileWriter.append(";");
}
fileWriter.append("\n");
fileWriter.flush();
}
catch (IOException e) {
e.printStackTrace();
}
}
When calling the method with generateCSV("myfile.csv") without the entries i don't get any compilation error. I thought that this notation implies passing 1-N parameters from this object type. No ?
It is fine to only pass a single parameter to this method: pColumns will then be a zero-length array.
If you want to require that at least one column name is passed, add an additional parameter:
private static void generateCSV(
String pFilename, String firstColumn, String... otherColumns) {
You then need to handle the first column specially:
fileWriter.append(firstColumn);
fileWriter.append(";");
for(String column : otherColumns) {
fileWriter.append(column);
fileWriter.append(";");
}
which is slightly less convenient than being able to treat them as a single array; but you just need to weigh that against the benefits of compile-time enforcement of having at least one column.

In Java how to assign value to System.in? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Writing data to System.in
We know that System.in (Standard Input) is connected to console. So whenever we write in console it will flow to this stream. But is there any way to pass value to this Standard Input without entering from console, i.e. like System.in = "ABCD". I just want to imitate as the value is passing from console.
Yes, there is. Use System.setIn(InputStream in).
You can supply any subtype of InputStream as well, so if you want to supply a specific value, you can use the StringBufferInputStream, like so:
StringBufferInputStream s = new StringBufferInputStream("ABCD");
System.setIn(s);
I think that instead of having your method directly access System.in:
public void process() {
byte b[] = new byte[4000];
int bytesRead = System.in.read(b);
...
}
You should factor that out so that an input stream is passed into the method:
public void run() {
process(System.in);
}
public void process(InputStream is) {
byte b[] = new byte[4000];
int bytesRead = is.read(b);
...
}
This gives you the same behavior, but lets you invoke the business logic with input streams of your own devising for test purposes, too.

Smarter println that shows the depth in the stack

I am using System.out.println in my code to track the execution of a program and get some useful output. This creates results like this in the console:
Main function. Program starts.
Method getArea. Getting values
Method getSide. Side is 6
Method getArea. First value is 6
Method getSide. Side is 8
Method getArea. Second value is 8
Method getArea. Area is 48
Main function. The final area is 48
I would like to create tha method, which adds a space in front of the output every time the code goes deeper in the method call stack. For example, the same code but instead of using System.out.println, now with Misc.smartPrintln:
Main function. Program starts.
Method getArea. Getting values
Method getSide. Side is 6
Method getArea. First value is 6
Method getSide. Side is 8
Method getArea. Second value is 8
Method getArea. Area is 48
Main function. The final area is 48
The method would have this definition:
public static void smartPrintln(String string);
I don't know how to implement this functionality. Any ideas how to solve this? And, could the use of a logger offer this functionality?
Create a temporary Throwable object.
Use its getStackTrace() method to analyze the stack and determine the level.
e.g.
public static void smartPrintln(String string) {
Throwable t = new Throwable();
StackTraceElement[] stackElements = t.getStackTrace();
int level = stackElements.length - 1; // don't forget our function adds a level
for (int i = 0; i < level; i++) {
System.out.print(' '); // could probably make this more efficient
}
System.out.println(string);
}
Interesting question. A more condense implementation of #ob1's suggestion:
public static void smartPrintln(String string) {
int i = new Throwable().getStackTrace().length - 1;
System.out.printf("%"+i+"s%s%n", "", string);
}
Another solution would be to "add the functionality" directly to System.out.println calls like this:
System.setOut(new PrintStream(System.out) {
public void println(String x) {
printf("%"+(new Throwable().getStackTrace().length - 1)+"s", "");
super.println(x);
}
});
After this point, all calls to System.out.println(String) will be processed by our "filtering" PrintStream implementation.
Use the Logger API or anyother third party API.

Categories