Results 1 to 10 of 10
  1. #1
    Join Date
    Mar 2016
    Posts
    93
    Rep Power
    0

    Default Help with lambda expressions

    Hi all. Once again, I'm trying to follow along with another concept in my text book. This time, it Lambda Expressions.

    ContactApp.java:
    Java Code:
    package contact.ui;
    import contact.business.*;
    import contact.db.*;
    
    public class ContactApp {
    	public static void main(String args[]){
    		new ContactApp().start();
    	}
    	public void start(){
    		ContactList list = new ContactList();
    		Contact c = list.filteredContactsLambdaTest();
    		System.out.println("The contacts without a phone number or email address are:");
    		
    		c.printAll();
    		c.filteredContacts();//call the method that will print all names that don't have a
    		//phone number and/or an email address		
    	}
    }
    Line 14 error: "The method printAll() is undefined for the type Contact"
    Line 15 error: "The method filteredContacts() is undefined for the type Contact":


    ContactList.java:
    Java Code:
    package contact.db;
    import contact.business.*;
    import java.util.ArrayList;
    
    public class ContactList {
    	ArrayList<Contact> contacts = new ArrayList<>();
    	contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    	contacts.add(new Contact("Sam Birdy", null, null));
    	contacts.add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
    	contacts.add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
    	contacts.add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
    	
    	public void printAll(){
    		System.out.println("for starters, the names of all of our contacts are:");
    		for(Contact c : contacts){
    			System.out.println(c);
    		}
    	}
    	
    	//Before you can code a lambda expression, you need to define the parameters and return type
    	//for the lambda expression using a functional interface:
    	public interface TestContact{
    		boolean test(Contact c);
    	}
    	
    	//A method that uses a functional interface to specify the filter condition:
    	public ArrayList<Contact> filterContacts(ArrayList<Contact> contacts, TestContact condition){
    		ArrayList<Contact> filteredContacts = new ArrayList<>();
    		for(Contact c : contacts){
    			if(condition.test(c)){//check if the Contact object should be added to the list by
    				//calling the test method of the TestContact object.
    				filteredContacts.add(c);
    				System.out.println(c);
    			}
    		}
    	}
    	public Contact filteredContactsLambdaTest(){
    		//Code with lambda expression that gets contacts that don't have phone numbers:
    		ArrayList<Contact> contactsWithoutPhone = filterContacts(contacts,
    						c -> c.getPhone() == null || c.getPhone().isEmpty());
    		//Code with lambda expression that gets contacts that don't have email addresses:
    		ArrayList<Contact> contactsWithoutEmail = filterContacts(contacts,
    						c -> c.getEmail() == null || c.getEmail().isEmpty());
    		return c;
    	}
    }
    Line 7 error: "Multiple markers at this line
    - Syntax error on token ".", @ expected after
    this token
    - Syntax error on token ";", @ expected"

    Lines 8 thru 10 error: "Syntax error on token ";", @ expected"

    Line 11 error: "Multiple markers at this line
    - Syntax error, insert "SimpleName" to complete
    QualifiedName
    - Syntax error, insert "Identifier (" to complete
    MethodHeaderName
    - Syntax error, insert ")" to complete MethodDeclaration"

    Doesn't eclipse recognize that the @ signs in the email addresses are part of a string enclosed in double quotes?

    Also, I'm still pretty new to ArrayList, so is the error on line 11 related to missing class constructors of some sort?

  2. #2
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,995
    Rep Power
    10

    Default Re: Help with lambda expressions

    You are adding contact to the contacts list in the class body. That is not allowed. Move the code to a constructor or a method.
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  3. #3
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    15

    Default Re: Help with lambda expressions

    Or use an initializer block to create the list.

    Java Code:
    List<Contact> contacts = new ArrayList<Contact>() {
          {
              add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
              add(new Contact("Sam Birdy", null, null));
              add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
              add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
              add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
          }
    };
    BTW, unless you need the extra methods of an implementation, best practice is to use the interface
    as the assignment target (in this case, List<T>).

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  4. #4
    Join Date
    Mar 2016
    Posts
    93
    Rep Power
    0

    Default Re: Help with lambda expressions

    Quote Originally Posted by SurfMan View Post
    You are adding contact to the contacts list in the class body. That is not allowed.
    In future posts, please state the .java file you're speaking of (instead of just saying class body). For example, say something like, "You are adding contact to the contacts list in the ContactList.java class body." That would save both of us some time.
    Quote Originally Posted by SurfMan View Post
    Move the code to a constructor or a method.
    Also in future posts, please copy and paste the portion of my code that you're talking about in your replies.

    Quote Originally Posted by jim829 View Post
    Or use an initializer block to create the list.
    That still didn't fix the errors from post #1:

    ContactList.java:
    Java Code:
    package contact.db;
    import contact.business.*;
    import java.util.ArrayList;
    
    public class ContactList {
    	ArrayList<Contact> contacts = new ArrayList<>();
    	contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    	contacts.add(new Contact("Sam Birdy", null, null));
    	contacts.add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
    	contacts.add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
    	contacts.add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
    	
    	public void printAll(){
    		System.out.println("for starters, the names of all of our contacts are:");
    		for(Contact c : contacts){
    			System.out.println(c);
    		}
    	}
    	
    	//Before you can code a lambda expression, you need to define the parameters and return type
    	//for the lambda expression using a functional interface:
    	public interface TestContact{
    		boolean test(Contact c);
    	}
    	
    	//A method that uses a functional interface to specify the filter condition:
    	public ArrayList<Contact> filterContacts(ArrayList<Contact> contacts, TestContact condition){
    		ArrayList<Contact> filteredContacts = new ArrayList<>();
    		for(Contact c : contacts){
    			if(condition.test(c)){//check if the Contact object should be added to the list by
    				//calling the test method of the TestContact object.
    				filteredContacts.add(c);
    				System.out.println(c);
    			}
    		}
    	}
    	public Contact filteredContactsLambdaTest(){
    		//Code with lambda expression that gets contacts that don't have phone numbers:
    		ArrayList<Contact> contactsWithoutPhone = filterContacts(contacts,
    						c -> c.getPhone() == null || c.getPhone().isEmpty());
    		//Code with lambda expression that gets contacts that don't have email addresses:
    		ArrayList<Contact> contactsWithoutEmail = filterContacts(contacts,
    						c -> c.getEmail() == null || c.getEmail().isEmpty());
    		return c;
    	}
    }
    Quote Originally Posted by Sam_JavaTheHut5580 View Post
    Line 7 error: "Multiple markers at this line
    - Syntax error on token ".", @ expected after
    this token
    - Syntax error on token ";", @ expected"

    Lines 8 thru 10 error: "Syntax error on token ";", @ expected"

    Line 11 error: "Multiple markers at this line
    - Syntax error, insert "SimpleName" to complete
    QualifiedName
    - Syntax error, insert "Identifier (" to complete
    MethodHeaderName
    - Syntax error, insert ")" to complete MethodDeclaration"

    Doesn't eclipse recognize that the @ signs in the email addresses are part of a string enclosed in double quotes?

    Also, I'm still pretty new to ArrayList, so is the error on line 11 related to missing class constructors of some sort?
    Why are there so many errors about the @ sign?

    Quote Originally Posted by jim829 View Post
    BTW, unless you need the extra methods of an implementation, best practice is to use the interface
    as the assignment target (in this case, List<T>).
    Now that you mention it, I'm clueless to what the test method in the interface from line 22 to 24 in ContactList.java is doing (if anything at all), especially since I'm not even calling the test method anywhere. Or am I already calling that method somewhere by a different name?

    Also, what does "use the interface as the assignment target" mean?

  5. #5
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    15

    Default Re: Help with lambda expressions

    Quote Originally Posted by Sam_JavaTheHut5580 View Post
    In future posts, please state the .java file you're speaking of (instead of just saying class body). For example, say something like, "You are adding contact to the contacts list in the ContactList.java class body." That would save both of us some time.

    Also in future posts, please copy and paste the portion of my code that you're talking about in your replies.
    So now you are telling us how we need to respond to your questions. Pretty arrogant considering we are taking time to
    help you learn Java. Yet you keep making the same mistakes. And you should not be doing anything with lambda's until
    you learn the fundamentals (which you aren't even close to yet).

    That still didn't fix the errors from post #1:
    That's because you did it wrong. But I don't know how since it isn't in your code. Read the Java tutorials.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  6. #6
    Join Date
    Mar 2016
    Posts
    93
    Rep Power
    0

    Default Re: Help with lambda expressions

    Quote Originally Posted by jim829 View Post
    Yet you keep making the same mistakes.
    Okay, I get where you're coming from. I've already learned how to use ArrayLists in another simpler project that only used static void and basic API-built-in-ArrayList methods, but I was so tunnel-visioned on syntax that I forgot that I needed a private instance variable, a default constructor, and getter in ContactList.java.

    Quote Originally Posted by jim829 View Post
    And you should not be doing anything with lambda's until
    you learn the fundamentals (which you aren't even close to yet)
    To save space, I left out some easier-to-understand (but less efficient) methods that I commented out. Here is a version of ContactList.java with those methods included:
    Java Code:
    package contact.db;
    import contact.business.*;
    import java.util.ArrayList;
    
    public class ContactList {	
    	public Contact getListOfContacts(){
    		ArrayList<Contact> contacts = new ArrayList<>();
    		contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    		contacts.add(new Contact("Sam Birdy", null, null));
    		contacts.add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
    		contacts.add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
    		contacts.add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
    		return contacts;
    	}
    	/*
    	ArrayList<Contact> contacts = new ArrayList<>();
    	contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    	contacts.add(new Contact("Sam Birdy", null, null));
    	contacts.add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
    	contacts.add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
    	contacts.add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
    	*/
    	public void printAll(){
    		System.out.println("for starters, the names of all of our contacts are:");
    		for(Contact c : contacts){
    			System.out.println(c);
    		}
    	}	
    	/*
    	//A method that returns contacts that don't have phone numbers:
    	public ArrayList<Contact> filterContactsWithoutPhone(ArrayList<Contact> contacts){
    		ArrayList<Contact> contactsWithoutPhone = new ArrayList<>();
    		for(Contact c : contacts){
    			if(c.getPhone() == null){
    				contactsWithoutPhone.add(c);
    			}
    		}
    		return contactsWithoutPhone;
    	}
    	//A method that returns contacts that don't have email addresses:
    	public ArrayList<Contact> filterContactsWithoutEmail(ArrayList<Contact> contacts){
    		ArrayList<Contact> contactsWithoutEmail = new ArrayList<>();
    		for(Contact c : contacts){
    			if(c.getPhone() == null){
    				contactsWithoutEmail.add(c);
    			}
    		}
    		return contactsWithoutEmail;
    	}
    	//A method that returns contacts that don't have an email address or phone number:
    	public ArrayList<Contact> filterContactsWithoutAnyContactInfo(ArrayList<Contact> contacts){
    		ArrayList<Contact> contactsWithoutAnyInfo = new ArrayList<>();
    		for(Contact c : contacts){
    			if(c.getPhone() == null){
    				contactsWithoutAnyInfo.add(c);
    			}
    		}
    		return contactsWithoutAnyInfo;
    	}
    	//Since the 3 methods above are so similar, code duplication makes it more difficult to
    	//maintain those methods. This situation calls for the use of a Lambda Expression.
    	*/
    }//end of ContactList class
    I could call those methods individually, but I'm trying to learn and understand how to write code that will achieve the same results as the filterContactsWithoutAnyContactInfo method Lambda style, but even with the book's example:
    Java Code:
    //Before you can code a lambda expression, you need to define the parameters and return type
    	//for the lambda expression using a functional interface:
    	public interface TestContact{
    		boolean test(Contact c);
    	}
    	
    	//A method that uses a functional interface to specify the filter condition:
    	public ArrayList<Contact> filterContacts(ArrayList<Contact> contacts, TestContact condition){
    		ArrayList<Contact> filteredContacts = new ArrayList<>();
    		for(Contact c : contacts){
    			if(condition.test(c)){//check if the Contact object should be added to the list by
    				//calling the test method of the TestContact object.
    				filteredContacts.add(c);
    				System.out.println(c);
    			}
    		}
    	}
    	public Contact filteredContactsLambdaTest(){
    		//Code with lambda expression that gets contacts that don't have phone numbers:
    		ArrayList<Contact> contactsWithoutPhone = filterContacts(contacts,
    						c -> c.getPhone() == null || c.getPhone().isEmpty());
    		//Code with lambda expression that gets contacts that don't have email addresses:
    		ArrayList<Contact> contactsWithoutEmail = filterContacts(contacts,
    						c -> c.getEmail() == null || c.getEmail().isEmpty());
    		return c;
    	}
    The main thing confusing me is how the TestContact interface even interacts with the filterContacts and filterdContactsLambdaTest methods. If you think this is even worth learning, feel free to try and explain the logic to me. Sorry if I was rude before.

  7. #7
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    27

    Default Re: Help with lambda expressions

    The interface used by a lambda expression is one that has a single method defined.
    That way the compiler knows exactly what method is represented by the lambda expression, in your case that method is called test and takes a single input of type Contact and returns a boolean.

    Essentially this code here:
    Java Code:
    c -> c.getPhone() == null || c.getPhone().isEmpty()
    is the equivalent of:
    Java Code:
    new TestContact() {
        public boolean test(Contact c) {
            return c.getPhone() == null || c.getPhone().isEmpty();
        }
    }
    But I'll echo jim in that you really shouldn't be worrying about lambda's if you can't identify a fairly simply compilation error caused by code not being in a code block.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  8. #8
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    15

    Default Re: Help with lambda expressions

    Quote Originally Posted by Sam_JavaTheHut5580 View Post
    Sorry if I was rude before.
    Not a problem. Now about initializer blocks (Toll's addressed the lambda question).
    I am leaving out most of your ContactList in the example.

    You had this.

    Java Code:
    public class ContactList {
     
            ArrayList<Contact> contacts = new ArrayList<>();
            contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    
    // rest of class
    But you get errors because you may not put the add statements (or other executable statements)
    directly in a class. They must be in methods.

    Then you replaced it with this, as Surfman suggested.

    Java Code:
    public class ContactList {
    
       public ArrayList<Contact> getListOfContacts(){ 
            ArrayList<Contact> contacts = new ArrayList<>();
            contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
            return contacts;
       }
    
       // rest of class
    which is a perfectly reasonable way to do it. Note: Your previous example had a return type of Contact
    which was wrong. You are returning a list of objects. Not a single object.

    But you can also use an initializer block. It is not in a method but directly in the class body.

    Java Code:
    public Class ContactList
    
       ArrayList<Contact> contacts = new ArrayList<Contact>() {
          {
            add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com","555-5555"));
            }
          };
    
       // rest of class
    Notice in the last example, I created an anonymous class so I didn't need to qualify the add invocations.
    I could have also done it like this.

    Java Code:
    public Class ContactList
        ArrayList<Contact> contacts = new ArrayList<>();
    
         {  
          contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com","555-5555"));
        }
    
        // rest of class


    And here is a final, unrelated example to initialize
    an array of ints to its indices (i.e. a[j] = j)

    Java Code:
    class Foo {
       int[] ints = new int[2000];
       { 
           for (int j = 0; j < ints.length; j++) {
              ints[j] = j;
           }
        }
        // rest of class
    Regards,
    Jim
    Last edited by jim829; 09-08-2016 at 03:37 PM.
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  9. #9
    Join Date
    Mar 2016
    Posts
    93
    Rep Power
    0

    Default Re: Help with lambda expressions

    I've reorganized my code into 5 classes, and finally compiled it successfully. However, I'm getting some bizarre output:

    Contact.java:
    Java Code:
    package contact.business;
    
    public class Contact {
    	private String name;
    	private String email;
    	private String phone;
    	
    	public Contact(){
    		this("", "", "");
    	}	
    	public Contact(String name, String email, String phone){
    		this.name = name;
    		this.email = email;
    		this.phone = phone;
    	}
    	
    	public void setName(String name){
    		this.name = name;
    	}
    	public String getName(){
    		return name;
    	}
    	public void setEmail(String email){
    		this.email = email;
    	}
    	public String getEmail(){
    		return email;
    	}
    	public void setPhone(String phone){
    		this.phone = phone;
    	}
    	public String getPhone(){
    		return phone;
    	}
    }
    ContactList.java:
    Java Code:
    package contact.db;
    import contact.business.*;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ContactList {	
    	private List<Contact> contacts;
    	
    	public ContactList(){
    		contacts = new ArrayList<>();
    		contacts.add(new Contact("Mr Buttkiss", "buttkiss@hotmail.com", "555-5555"));
    		contacts.add(new Contact("Sam Birdy", null, null));
    		contacts.add(new Contact("Don Krieg", "blitzkrieg@gmail.com", null));
    		contacts.add(new Contact("Uncle Dukey", "", "839-7411"));//email address isEmpty() tester
    		contacts.add(new Contact("Big Daddy", "bigdaddy@yahoo.com", ""));//phone number isEmpty() tester
    	}
    	public List<Contact> getContacts() {
            return contacts;
        }
    	public void printAll(){
    		System.out.println("for starters, the names of all of our contacts are:");
    		for(Contact c : contacts){
    			System.out.println(c);
    		}
    	}	
    }//end of ContactList class
    ContactFilter.java:
    Java Code:
    package contact.business;
    
    import java.util.ArrayList;
    import java.util.List;
    import contact.db.*;
    
    	public class ContactFilter {
    	private List<Contact> filteredContacts;
        
        public ContactFilter() {
        	filteredContacts = new ContactList().getContacts();
        }
        
        public List<Contact> getFilteredContactsByLambda(TestContact condition) {
            List<Contact> contacts = new ArrayList<>();
            for (Contact c: filteredContacts) {
                if (condition.test(c)) {//uses the lambda statements in ContactApp.java
                	contacts.add(c);
                }
            }
            return contacts;
        }
    }
    ContactApp.java:
    Java Code:
    package contact.ui;
    import java.util.List;
    import contact.business.*;
    
    public class ContactApp {
    	public static void main(String args[]){
    		new ContactApp().start();
    	}
    	public void start(){
    		ContactFilter contacts = new ContactFilter();
    		
    		List<Contact> contactsWithoutPhone = contacts.getFilteredContactsByLambda(
    				c -> c.getPhone() == null || c.getPhone().isEmpty());//getter used from Contact.java
            System.out.println("\nContacts without a phone number include:");
            printContactNames(contactsWithoutPhone);
            
            List<Contact> contactsWithoutEmail = contacts.getFilteredContactsByLambda(
            		c -> c.getEmail() == null || c.getEmail().isEmpty());
            System.out.println("\nContacts without an email address include:");
            printContactNames(contactsWithoutEmail);
            
        	
    	}//end of start method
    	public static void printContactNames(List<Contact> contactName) {
            for (Contact c : contactName) {
                System.out.println(c);
            }
        }
    }
    The interface (TestContact.java):
    Java Code:
    package contact.business;
    
    public interface TestContact {
    	boolean test(Contact c);
    }
    The output I got was:
    Help with lambda expressions-bizarreoutput.png

    From the looks of it, I would guess that I'm getting some sort of hexadecimal reference addresses, followed by a package statement path with an @ sign. But what is causing this strange behavior? Why isn't it printing the print string fields defined in my ArrayList populating statements (lines 11 to 15 in ContactList.java)?

  10. #10
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    15

    Default Re: Help with lambda expressions

    Your assessment on what is printing is close. But the ArrayList is populated with Contact objects. So
    you need to override the toString method in your Contacts class and return a String value containing
    whatever you want printed.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

Similar Threads

  1. Regular expressions
    By freelancer in forum New To Java
    Replies: 1
    Last Post: 11-25-2011, 12:41 PM
  2. Regular Expressions Help
    By Death Sickle in forum New To Java
    Replies: 4
    Last Post: 04-04-2011, 04:21 AM
  3. regular expressions
    By sozeee in forum New To Java
    Replies: 3
    Last Post: 12-06-2010, 09:58 PM
  4. JSP Expressions
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 12-26-2007, 10:13 AM
  5. JSP Expressions
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 12-02-2007, 09:35 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •