Cannot find symbol of written method java.util.function - java

I have code like
public class Functionz {
public static boolean test() {
return true;
}
public static void main(String[] args) {
Function[] funcs = new Function[] {test}; // and others
for (Function func : funcs) {
func();
}
}
}
and my error is: cannot find symbol: test in the line with the function array declaration.
Hope this isn't a stupid question, very new to java, not new to object oriented languages like python and C++.

A Function in Java does takes one parameter as input and one as output.
You might declare parameter's type this way : Function<Integer, String> is a function that transforms an Integer into a String
Your method test() does not take any input value and outputs a boolean so it's a Supplier.
import java.util.function.Supplier;
public class Main {
public static boolean test() {
System.out.println("lorem ipsum");
return true;
}
public static void main(String[] args) {
Supplier[] funcs = new Supplier[] {Main::test}; // and others
for (Supplier func : funcs) {
func.get();
}
}
}
Your code would compile if test requires one (and only one parameter) like
import java.util.function.Function;
public class Main {
public static boolean test(String str) {
System.out.println(str);
return true;
}
public static void main(String[] args) {
Function[] funcs = new Function[] {(Object anyObject) -> test(anyObject.toString())}; // and others
for (Function func : funcs) {
func.apply("lorem ipsum");
}
}
}
Here's the list of those types
Please note that Function doesn't type its parameters in construction because you can't create arrays with generic type in Java (you might for specific usecases) => Use a List will help you here

Related

confusion with Java wildcards

Please explain to me why I have one example that compiles and the other one doesn't compile
This is example that compiles
import java.util.ArrayList;
public class MyClass1 <T> {
public ArrayList<MyClass1<?>> lst;
public MyClass1()
{
lst = new ArrayList<MyClass1<?>>();
}
public static void main(String[] args) {
M(new MyClass1<Double>());
}
public static <T1> void M(MyClass1<T1> t1)
{
var d0 = new MyClass1<Double>();
d0.lst.add(t1);
}
}
But that doesn't compiles
import java.util.ArrayList;
public class MyClass1 <T> {
public ArrayList<?> lst;
public MyClass1()
{
}
public static void main(String[] args) {
M(Double.valueOf(1.1));
}
public static <T1> void M(T1 t1)
{
var d0 = new MyClass1<Double>();
d0.lst.add(t1); // error — java: incompatible types: T1 cannot be converted to capture#1 of ?
}
}
Why in the first case I have wildcard, and everything is OK, but in the second case I have wildcard and it doesn't compile
The second snippet can not be compiled because the generics in Java are about type safety(type guarantee). Thus, if we are declearing List<Integer> the compiler is convinced, that the list will contain only integers. But when we have List<?> (read this like list of some type), compiler cant predict what will the list contain. Today we are adding Integers, tomorrow somebody else will add a ServerSocket. In runtime if we will try to get a value from such a list, we will get a ClassCastException. That is why this code cant even be compiled - to prevent such situations. Read about type erasure and bridge methods.
In your concrete case, i guess, you would like to have something like this:
public class MyClass<T> {
public ArrayList<T> lst;
public static void main(String[] args) {
var obj = new MyClass<Double>();
obj.foo(1.1);
}
public void foo(T s) {
lst.add(s);
}
}
The question mark also can be useful:
static void m(List<? extends Shape> list) {
for (Shape el : list) {
// we are not quite interested what type is this list of.
}
}
And the usage example:
m(new ArrayList<Circle>());
m(new ArrayList<Shape>());

Why is it not possible to implement a functional interface using a lambda expression outside a class?

One can implement a functional interface this way:
abstract class predicate implements Predicate<Integer> {
public static boolean test(int e) {
return true;
}
}
or this way:
Predicate<Integer> predicate = e -> true;
The following code compiles:
import java.util.function.*;
abstract class predicate implements Predicate<Integer> {
public static boolean test(int e) {
return true;
}
}
public class Main
{
public static void main(String[] args) {
System.out.println(predicate.test(2));
}
}
But this code doesn't and gives a "class, interface, or enum expected" error:
import java.util.function.*;
Predicate<Integer> predicate = e -> true;
public class Main
{
public static void main(String[] args) {
System.out.println(predicate.test(2));
}
}
For the above code to work, I'd have to implement the interface inside the main class. Why?
Fields (even constant fields) must be defined in the class, and here you're using it like you expect it to be a static constant. Like,
public class Main {
private static final Predicate<Integer> predicate = e -> true; // PREDICATE by convention
public static void main(String[] args) {
System.out.println(predicate.test(2));
}
}

condition statement without if and switch

I have this code :
public static void main(String[] args){
boolean greeting = true; //or false
if(greeting)
hello();
}
public static void hello(){
System.out.println("Hello")
}
I want to call hello method without using (if,switch) if the value of greeting is set to true
is it possible to re-write this program without using if statement or switch ? if so how?
You can use an enum
enum Greeting {
GREETING(() -> System.out.println("hello")),
NO_GREETING(() -> {});
private final Runnable greeting;
private Greeting(Runnable r) {
greeting = r;
}
public void greet() {
greeting.run();
}
}
and then have
public static void main(String[] args) {
Greeting gr = Greeting.GREETING; // or Greeting.NO_GREETING
// or if you insist on the boolean
// Greeting gr = (greeting) ? Greeting.GREETING : Greeting.NO_GREETING;
gr.greet();
}
That would also be extendable to have things like
CORDIAL_GREETING(() -> System.out.println("hi wow so nice to see you"))
in the enum.
The ternary operator in the comment is of course not really different from an if/else.
checkout this :
public static void main(String[] args)
{
boolean b = true;
Predicate<Boolean> p = s -> {hello();return true;};
boolean notUsefulVariable = b && p.test(true); //will be called
b = false;
notUsefulVariable = b && p.test(true); //will not called
}
public static void hello(){
System.out.println("Hello");
}
or you could use while
b = true;
while(b)
{
hello();
break;
}
Simple answer:
public static void main(String[] args){
boolean greeting = true; //or false
while(greeting) {
hello();
break;
}
}
It may not be very elegant, but that wasn't the question, and it's the simplest solution (at least, that I can think of).
If modification of greet() is allowed, one can do it with very little changes to the original code:
public static void main(String[] args) {
boolean greet = true;
boolean dummy = greet && greet();
}
public static boolean greet() {
System.out.println("Hello");
return true;
}
There are a number of ways to branch into a block of code without an if statement. I'll start with simple, and move to the complex.
You can use a switch statement. It is basically a compound ifstatement, with more conditions.
You can use the ternary operator ?. This replaces the condition with one of two values, and can be used like an if statement.
You can use conditional jumping. Basically you store the body of the block of code for each result of the condition as the value in a Map, with the key being the value of the evaluated condition. Then you evaluate the condition, and run the code. For example
myMap.get(age > 3).execute();
Where myMap is a Map with
Map(true) = block of code to `execute()` if true.
Map(false) = block of code to `execute()` if false.
There's lots of ways to go about it. These are just some common ones.
--- Edited with example, as Przemysław Moskal asked for one :) ---
I see your confusion about ternary and returning null, but the poster isn't going to print null in either case of their conditional, they are going to print a String.
public class Hello {
private static Map<Boolean, String> response;
public static void main(String[] args) {
// setup the response map
response = new HashMap<>();
response.put(Boolean.TRUE, "Hello");
response.put(Boolean.FALSE, "");
boolean value = true;
System.out.println(response.get(value));
}
}
or another approach
public class Hello {
private static Map<Boolean, Runnable> response;
public static void main(String[] args) {
// setup the response map
response = new HashMap<>();
response.put(Boolean.TRUE, new Runnable() {
public void run() {
System.out.println("Hello");
}
});
response.put(Boolean.FALSE, new Runnable() {
public void run() {
}
})
boolean value = true;
response.get(value).run();
}
}
or anther example
System.out.println((condition) ? "Hello" : "");
However, it is quite possible for a ternary operation to return null.
(condition) ? null : "hi";
is a valid expression, provided that the null or the hi are both valid in the context of where you write that expression.
I think it's only a Compiler trick question.
Based on the question : greeting is set to true or false, not changeable vairable.
If we set : boolean greeting = true;, the Compiler ignores if command and delete it.
public static void main(String[] args){
boolean greeting = true;
// if(greeting) ---ignores with Compiler
hello();
}
However, if we set : boolean greeting = false;, the Compiler ignores all the if command as Dead Code and delete all the if.
public static void main(String[] args){
boolean greeting = false;
// if(greeting) ---ignores with Compiler as Dead Code
// hello(); ---ignores with Compiler as Dead Code
}
Therefor: if greeting set to true: there is no need to if. And if greeting set to false: there is no need to if and hello() method. So there is not any if in the final code to change it to other things.
As my first attempt to answer this question was not well received, I tried to make another one.
After a little discussion under one of the answers to this question, I was looking for a way to use ternary operator (condition ? value1 : value2) to call method whose return value is void and I think it's rather impossible, because value1 and value2 can't be result of calling such method as hello() returns nothing. If there is a need to use ternary operator, I guess this is the only possible way to make use of this operator, with making the least additional operations possible:
public class MyClass {
public static void main(String[] args){
boolean greeting = true; //or false
checkIfGreetingIsTrue(greeting);
}
public static void hello(){
System.out.println("Hello");
}
public static Void checkIfGreetingIsTrue(boolean greeting) {
return greeting ? callHelloInMyBody() : null;
}
public static Void callHelloInMyBody() {
hello();
return null;
}
}

How to a key in java that the value comes froma string

I want to set a key in java from the value that is set from a string
sorry i cant explain this to good so i wrote this in php and here
is a example.
class Test() {
public setField($key, $value) {
$this->{$key} = $value;
}
}
$class = new Test()
$class->setField("hello", "hello world");
echo $class->hello;
The map interface gives the requested behavior:
import java.util.HashMap;
public class StackOverflow {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("hello", "hello world");
System.out.println(map.get("hello"));
}
}
But you generally want to use variables as keys, and then you would need a method for setting and retrieving every variable.
public class Test {
private String hello;
public void setHello(String hello) {
this.hello = hello;
}
public String getHello() {
return hello;
}
}
public class StackOverflow {
public static void main(String[] args) {
Test test = new Test();
test.setHello("Hello world");
System.out.println(test.getHello());
}
}
Or you could make the variable public:
public class Test {
public String hello;
}
public class StackOverflow {
public static void main(String[] args) {
Test test = new Test();
test.hello = "Hello world";
System.out.println(test.hello);
}
}
Java does not have in-built dynamic variables like PHP. The simplest way to achieve the same functionality this is be to use a Map
public class Test {
private Map<String, String> map = new HashMap<String, String>();
public void setField(String key, String value) {
map.put(key, value);
}
public String getField(String key) {
return map.get(key);
}
}
and
Test test = new Test();
test.setField("hello", "hello world");
System.out.println(test.getField("hello"));
You'll have to do it manually in Java. Something along the lines of:
class Test(){
private HashMap<Object, Object> inner_objects;
public void setField(Object key, Object value) {
this.inner_objects.put(key, value);
}
public Object getField(Object key){
return this.inner_objects.get(key);
}
}
Of course this example could be improved in several ways, but it is just to give you the general idea.
But since there is no operator overloading, you can't make -> work as getField, so you will need to call getField(key) everytime.

Using an interface as a constructor parameter in Java?

How would I be able to accomplish the following:
public class testClass implements Interface {
public testClass(Interface[] args) {
}
}
So that I could declare
Interface testObject = new testClass(new class1(4), new class2(5));
Where class1 and class2 are also classes that implement Interface.
Also, once I accomplish this, how would I be able to refer to each individual parameter taken in to be used in testClass?
Thanks :)
So that I could declare
Interface testObject = new
testClass(new class1(4), new
class2(5));
You need to use varargs in testClass constructor:
public testClass (Interface ... args) {
for (Interface i : args) {
doSmthWithInterface (i);
}
}
You can use varargs, which are treated as arrays. For example:
public testClass(Interface... args) {
System.out.println(args[0]);
}
Like this (save the whole sample into a file, say testClass.java):
interface Interface{}
public class testClass implements Interface
{
public testClass(Interface ... args)
{
System.out.println("\nargs count = " + args.length);
for( Interface i : args )
{
System.out.println( i.toString() );
}
}
public static void main(String[] args)
{
new testClass(
new Interface(){}, // has no toString() method, so it will print gibberish
new Interface(){ public String toString(){return "I'm alive!"; } },
new Interface(){ public String toString(){return "me, too"; } }
);
new testClass(); // the compiler will create a zero-length array as argument
}
}
The output will be as follows:
C:\temp>javac testClass.java
C:\temp>java testClass
args count = 3
testClass$1#1f6a7b9
I'm alive!
me, too
args count = 0
You don't have to use varargs, you can use an array as an input parameter, varargs is basically just a fancy new syntax for an array parameter, but it will help prevent you from having to construct your own array in the calling class.
i.e. varargs allow (parm1, parm2) to be received into an array structure
You cannot use an interface to enforce a Constructor, you should probably use a common abstract super class with the desired constructor.
public abstract class Supa {
private Supa[] components = null;
public Supa(Supa... args) {
components = args;
}
}
public class TestClass extends Supa {
public TestClass(Supa... args) {
super(args);
}
public static void main(String[] args) {
Supa supa = new TestClass(new Class1(4), new Class2(5));
// Class1 & Class2 similarly extend Supa
}
}
Also see the composite design pattern http://en.wikipedia.org/wiki/Composite_pattern

Categories

Resources