I’ve been trying to find explanations or videos for so long explaining void methods to me and I just don’t get it still. Everyone just says “they dont return any value” i already know that. I don’t know what that means tho? You can still print stuff with them and u can assign variables values with them i don’t get how they are any different from return methods and why they are needed?
Videos
You are trying to use the wrong interface type. The type Function is not appropriate in this case because it receives a parameter and has a return value. Instead you should use Consumer (formerly known as Block)
The Function type is declared as
interface Function<T,R> {
R apply(T t);
}
However, the Consumer type is compatible with that you are looking for:
interface Consumer<T> {
void accept(T t);
}
As such, Consumer is compatible with methods that receive a T and return nothing (void). And this is what you want.
For instance, if I wanted to display all element in a list I could simply create a consumer for that with a lambda expression:
List<String> allJedi = asList("Luke","Obiwan","Quigon");
allJedi.forEach( jedi -> System.out.println(jedi) );
You can see above that in this case, the lambda expression receives a parameter and has no return value.
Now, if I wanted to use a method reference instead of a lambda expression to create a consume of this type, then I need a method that receives a String and returns void, right?.
I could use different types of method references, but in this case let's take advantage of an object method reference by using the println method in the System.out object, like this:
Consumer<String> block = System.out::println
Or I could simply do
allJedi.forEach(System.out::println);
The println method is appropriate because it receives a value and has a return type void, just like the accept method in Consumer.
So, in your code, you need to change your method signature to somewhat like:
public static void myForEach(List<Integer> list, Consumer<Integer> myBlock) {
list.forEach(myBlock);
}
And then you should be able to create a consumer, using a static method reference, in your case by doing:
myForEach(theList, Test::displayInt);
Ultimately, you could even get rid of your myForEach method altogether and simply do:
theList.forEach(Test::displayInt);
About Functions as First Class Citizens
All been said, the truth is that Java 8 will not have functions as first-class citizens since a structural function type will not be added to the language. Java will simply offer an alternative way to create implementations of functional interfaces out of lambda expressions and method references. Ultimately lambda expressions and method references will be bound to object references, therefore all we have is objects as first-class citizens. The important thing is the functionality is there since we can pass objects as parameters, bound them to variable references and return them as values from other methods, then they pretty much serve a similar purpose.
When you need to accept a function as argument which takes no arguments and returns no result (void), in my opinion it is still best to have something like
public interface Thunk { void apply(); }
somewhere in your code. In my functional programming courses the word 'thunk' was used to describe such functions. Why it isn't in java.util.function is beyond my comprehension.
In other cases I find that even when java.util.function does have something that matches the signature I want - it still doesn't always feel right when the naming of the interface doesn't match the use of the function in my code. I guess it's a similar point that is made elsewhere here regarding 'Runnable' - which is a term associated with the Thread class - so while it may have he signature I need, it is still likely to confuse the reader.
First, the multiply method does not return anything; it prints the product, but does not return any value.
public static void multiply(int x, int y)
{
int z = x*y;
System.out.println(z); //may look like a return, but actually is a side-effect of the function.
} //there is no return inside this block
Secondly, public static void main provides an entry point into your program. Without it, you cannot run your program. Refer to the Java documentation for more information on the usage of public static void main.
The String[] args here means that it captures the command line arguments and stores it as an array of strings (refer to the same link posted above, in the same section). This array is called args inside your main method (or whatever else you call it. Oracle cites argv as an alternate name)
System.out.print tells the program to print something to the console, while return is the result of the method. For example, if you added print all over your method to debug (a common practice), you are printing things while the program runs, but this does not affect what the program returns, or the result of the program.
Imagine a math problem - every step of the way you are "print"ing your work out onto the paper, but the result - the "answer" - is what you ultimately return.
When a method does not return anything, you specify its return type as "void". Your multiply method is not returning anything. Its last line is a print statement, which simply prints the value of its arguments on the standard output. If the method ended with the line "return z", then you would not be able to compile the program with the "void" return type. You would need to change the method signature to public static int multiply(int x, int y).
All Java programs do require the public static void main(String[] args) if they are to be executable. It is the starting point of any runnable Java program. Here's what it means:
a. public - the main method is callable from any class. main should always be public because it is the method called by the operating system.
b. static - the main method should be static, which means the operating system need not form an object of the class it belongs to. It can call it without making an object.
c. void - the main method does not return anything (although it may throw an Exception which is caught by the operating system)
d. String[] args - when you run the program, you can pass arguments from the command line. For example, if your program is called Run, you can execute the command java Run 3 4. In that case, the arguments would be passed to the program Run in the form of an array of Strings. You would have "3" in args[0] and "4" in args[1].
That said, you could have a Java program without a main, which will not be runnable.
I hope that helps.
Because there is a a difference between "This function can succeed or fail and is self-aware enough that it can tell the difference" and "There is no feedback about the effect of this function." Without void, you'd endlessly check success codes and believe that you are writing robust software, when in fact you are doing nothing of the sort.
- Because C has a
voidtype, and Java was designed to follow many of the conventions of the C language family. - There are many functions that you don't want to have return a value. What are you going to do with "a generic
Successtype" anyway? In fact, return values to indicate success are even less important in Java than in C, because Java has exceptions to indicate failure and C doesn't.