I have a function e.g.
helloworld(list<object> names)
I have the following code :
List<CustomClass> newMe = new ArrayList<CustomClass>();
Now, if i want to pass newMe into helloworld(newMe);. This is not possible because im down casting. How can i overcome this issue? Do i downcast my list to (Object) and then try to upcast it? is there another way? would appreciate an example.
thanks
Change the definition of helloworld to
public void helloworld(List<?> names) {
//method implementation...
}
Take into account that your method won't be able to add or remove elements from the list parameter.
Just use a ? as generic type in your parameter list. Example:
public class Foobar {
public static void helloworld(List<?> names) {
}
public static void main(String[] args) {
List<CustomClass> newMe = new ArrayList<>();
helloworld(newMe);
}
}
Related
I am wondering if ya'll can help me get a better grip on generics.
I have simplified this question as much as possible.
I am trying to save the element stored in a linked list in a variable called saveIt. I know LinkedList itself uses generics, so I want my variable to take up whatever data type is in the list. I believe LinkedList itself designates that type as E, but when I try to declare a variable as 'E saveIt' I get "cannot resolve symbol E."
public class Main {
public static void main(String[] args) {
// whatever goes here ...
}
void saveElement(LinkedList input) {
E saveIt = input.getFirst();
}
}
If I make the LinkedList then I can declare a variable as 'Integer saveIt' but that isn't what I want to do.
public class Main {
public static void main(String[] args) {
// whatever goes here ...
}
void saveElement(LinkedList<Integer> input) {
Integer saveIt = input.getFirst();
}
}
I considered declaring 'Object saveIt' but I'm not sure whether that is the right approach. The concept of datatype E obviously exists in Java, and isn't quite the same as Object (or is it?), so why can't I access it (or how can I access it)?
public class Main {
public static void main(String[] args) {
// whatever goes here ...
}
void saveElement(LinkedList input) {
Object saveIt = input.getFirst();
}
}
So, basic question is if I want to have my method address whatever datatype is in the list, how do I do that?
<E> void saveElement(LinkedList<E> input) {
E saveIt = input.getFirst();
}
You need to tell Java that E is a type parameter of your method -- it's like another thing that's being passed in! -- and that the LinkedList contains elements of type E.
I hope you can help me as I am new to Java-8
public class main {
public static void main(String[] args){
ArrayList<Double> coll1 = new ArrayList<>();
coll1.add(2.5);
coll1.add(3.5);
printColl(multi(coll1));
}
public static ArrayList<Double> multi(ArrayList<Double> coll1) {
return coll1.replaceAll(aDouble -> aDouble*2.0);
}
public static void printColl(ArrayList<?> coll) {
coll.stream().forEach(System.out::println);
}
}
I have the following problem: I have an ArrayList with 2 Doubles, which I am trying to modify with the method "multi". I use the method "replaceAll" to change the single values with the lambda-expression but I get an error.
The error is "incompatible types. Required: java.util.List Found: void"
I hope you can help me as I really dont know why I am getting this error.
Let's have a look at the replaceAll method signature:
public void replaceAll(UnaryOperator<E> operator)
as you can see it does not return anything, that means it modifies the existing ArrayList.
so in your case, you would need to do something like:
public static ArrayList<Double> multi(ArrayList<Double> coll1) {
coll1.replaceAll(aDouble -> aDouble*2.0);
return coll1;
}
I'm learning to code java and I encountered some problems in which I could use help understanding how things work.
I've made a list containing "Images", on my Main class, called "myList".
public class Main{
public static void main(String[] args) {
List<Images> myList = new ArrayList<Images>();
...
And I want to access it on this "System" class. But it doesn't seem to let me.
The plan is to access a position (the 3rd, in this example) on the given list (list.get(2)).
So I created the method "work".
//Example
public class System{
public static boolean work(List<Images> list){
if( list.get(2).equals(Something) )
return false;
else ... return true;
}
On this same System class I'm trying to use the method "work", giving it the List that I created on my Main class (myList).
public class System{
...
if( work(myList) ) //Don't know how to reffer to myList
return something;
Gives me the error "myList cannot be resolved to a variable".
So the problem is how to reffer to the list I made on my Main, named "myList".
Not sure if I explained that too well but any suggestions?
Make a List a property of System class, then pass it in the constructor
public class System {
private List<Images> images;
public System(List<Images> images) {
this.images = images;
}
//your other methods
}
Ah, in your main you should also pass the list:
System system = new System(myList);
Another option its to make myList public static and access it like this:
Main.myList
Declare one helper class and declare your list with setter and getters. Mainatin a singleton object of this class and use that list then in different other classes.
you need to make sure its accessible.
Right now your list is scoped the main() function. which is static to boot.
You need to make it accessible. You can do this by storing it in a static variable and having a static function return it.
Or you pass the main object along to other object, so they can access it.
public class Main {
private List<Images> myList = new ArrayList<Images>();
public static void main(String[] args) {
new Main(args);
}
public Main(String[] args) {
myList.add('foo.png');
myList.add('bar.png');
System mySystem = new System(this);
}
public List<Images> getImages() {
return myList();
}
}
public class System{
Main global;
public System(Main main) {
global = main;
}
public void doSomething() {
Iterator<Images> it = global.getImages().iterator();
while(it.hasNext()) {
Images images = it.next();
}
}
}
I would like to create a class that store a list of methods references and then executes all of them using Java 8 Lambda but I have some problem.
This is the class
public class MethodExecutor {
//Here I want to store the method references
List<Function> listOfMethodsToExecute = new LinkedList<>();
//Add a new function to the list
public void addFunction(Function f){
if(f!=null){
listOfMethodsToExecute.add(f);
}
}
//Executes all the methods previously stored on the list
public void executeAll(){
listOfMethodsToExecute.stream().forEach((Function function) -> {
function.apply(null);
}
}
}
This is the class that I created for test
public class Test{
public static void main(String[] args){
MethodExecutor me = new MethodExecutor();
me.addFunction(this::aMethod);
me.executeAll();
}
public void aMethod(){
System.out.println("Method executed!");
}
}
But there is something wrong when I pass this::aMethod using me.addFunction.
What is wrong?
You should provide a suitable functional interface which abstract method signature is compatible with your method reference signature. In your case it seems that Runnable instead of Function should be used:
public class MethodExecutor {
List<Runnable> listOfMethodsToExecute = new ArrayList<>();
//Add a new function to the list
public void addFunction(Runnable f){
if(f!=null){
listOfMethodsToExecute.add(f);
}
}
//Executes all the methods previously stored on the list
public void executeAll(){
listOfMethodsToExecute.forEach(Runnable::run);
}
}
Also note that in static main method this is not defined. Probably you wanted something like this:
me.addFunction(new Test()::aMethod);
You can't refer to this in a static context as there is no this
me.addFunction(this::aMethod);
You need to refer to an instance or define your Function to take a Test object.
public void addFunction(Function<Test, String> f){
if(f!=null){
listOfMethodsToExecute.add(f);
}
}
and
me.addFunction(Test::aMethod);
This question already has answers here:
Is there a way to compare lambdas?
(3 answers)
Closed 7 years ago.
I am not sure how I can be sure about equality/immutability of functional interface.
I guess there might be no way to assure equality when I use this syntactic sugar in java 8, please let me know any hint if you have any.
I made a short code snippet for my question.
public interface Element {
void doSomething(int a);
}
and I've tried to add instance of this interface in functional way
public class FunctionSet {
public void doubleUp(int a) {
System.out.println(a*2);
}
public void square(int a) {
System.out.println(a*a);
}
public static void main(String[] args) {
HashSet<Element> set = new HashSet<>();
FunctionSet functionSet = new FunctionSet();
set.add(functionSet::doubleUp);
set.add(functionSet::square);
System.out.println(set.add(functionSet::doubleUp));
}
}
it prints true which means there were not any equality check and also I can't remove any instance from Set once I add it.
in case I use functional interface as an argument, Is there any way that I can compare those instance somehow?
will appreciate any help, thanks in advance!
You can store your method reference into a variable:
public static void main(String[] args) {
HashSet<Element> set = new HashSet<>();
FunctionSet functionSet = new FunctionSet();
Element fn = functionSet::doubleUp;
set.add(fn);
set.add(functionSet::square);
System.out.println(set.add(fn));
}
This way it returns false.
When you create the same labmda or method reference in different code locations, it's roughly the same as you would create a new anonymous class in both positions:
public static void main(String[] args) {
HashSet<Element> set = new HashSet<>();
FunctionSet functionSet = new FunctionSet();
set.add(new Element() {
#Override
public void doSomething(int a) {
functionSet.doubleUp(a);
}
});
set.add(new Element() {
#Override
public void doSomething(int a) {
functionSet.square(a);
}
});
System.out.println(set.add(new Element() {
#Override
public void doSomething(int a) {
functionSet.doubleUp(a);
}
}));
}
So every time it's a different object, though it may look the same. For every encountered method reference separate anonymous class is created at the runtime:
Element e1 = functionSet::doubleUp;
Element e2 = functionSet::doubleUp;
System.out.println(e1.getClass());
System.out.println(e2.getClass());
The output will be like this:
class FunctionSet$$Lambda$1/918221580
class FunctionSet$$Lambda$2/1554547125
So practically it's two distinct objects of two distinct classes. It would be quite difficult to conclude that they do the same thing without comparing their bytecode. Also note that they both capture the functionSet variable, so it should also be ensured that it wasn't changed between two method references.
The only workaround I can think up is to declare all the method references as constants in your code and later reference them instead of using method references directly:
public static final Element FN_DOUBLE_UP = new FunctionSet()::doubleUp;
public static final Element FN_SQUARE = new FunctionSet()::square;
public static void main(String[] args) {
HashSet<Element> set = new HashSet<>();
set.add(FN_DOUBLE_UP);
set.add(FN_SQUARE);
System.out.println(set.add(FN_DOUBLE_UP));
}