From user comments for Java Tutorials.
=======================================================================
Subject: Why this code have this?
Date: Thu, 17 Oct 2013 15:46:04 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html
Code on this link also work good without this:
InnerEvenIterator iterator = this.new InnerEvenIterator();
I newbie in Java and don't understand - why this code have this and why this example compile and run without this. Maybe other readers of this Java Tutorial will have the same questions.
Thank you.
</quote>
Thanks for pointing this out; the example on this page is quite old and it needs to be updated. As an FYI, Java SE 8 is introducing aggregate operations, which moves away from the iterator model:
http://docs.oracle.com/javase/tutorial/collections/streams/
=======================================================================
Subject: Mistake in text?
Date: October 22, 2013 7:40 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
This method invokes the method printPerson on each Person instance.
But printPerson() invoke only if (tester.test(p)), yes?..
</quote>
Yes, we'll clarify that printPerson is only invoked if tester.test(p) returns true.
=======================================================================
Subject: (No subject)
Date: October 23, 2013 6:35 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
You can specify the action performed on each Person instance with a lambda expression. Remember, to use a lambda expression, you need to implement a functional interface. In this case, you need a functional interface that contains a method that takes one argument (an object of type Person) and returns void. The Consumer<T> interface contains the method void accept(T t). The following method replaces the invocation p.printPerson() with an instance of Consumer<Person> that invokes the method accept:
public static void processPersons(
List<Person> roster,
Predicate<Person> tester,
Consumer<Person> block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
I read this again and again but can't clearly understand this piece of text. Why we need method that return void - I think that we need true or false for testing people for entering for search criteria, no? I just learn Java and maybe for future readers you can explain idea behind this piece of article more simple and clearly?
Thank you.
</quote>
We need to clarify this paragraph. It's not about tester but about block (what to do with each Person instance, which is to print something out in this example). The tester lambda expression was discussed in the previous section, Approach 6: Use Standard Functional Interfaces with Lambda Expressions.
=======================================================================
Subject: Mistake in code?
Date: Thu, 24 Oct 2013 00:47:08 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/examples/Person.java
Here we have this piece of code:
public int getAge() {
return birthday
.until(IsoChronology.INSTANCE.dateNow())
.getYears();
}
and this:
public LocalDate getBirthday() {
return birthday;
}
1) Return birthday two times?
2) Return birthday in method getAge?
</quote>
The field birthday is of type LocalDate, which is part of the new Date-Time API:
http://docs.oracle.com/javase/tutorial/datetime/index.html
The method getBirthday is a getter method. The sample code uses getAge, which returns an int, to help it compare ages.
==================================================================
Subject: Not clear piece of article: Lambda Expressions: Approach 3
Date: October 24, 2013 11:00 AM
<quote>
Hi, I am about this page.
Approach 3: Specify Search Criteria Code in a Local Class - this part of article is not very clear:
Here we have:
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
But below:
printPersons(roster, new CheckPersonEligibleForSelectiveService());
Why this call have arguments, but in call above - p.printPerson(); - we don't have arguments?
And what is tester? In Approach 3 this word (class?) not described :(
And when we do new CheckPersonEligibleForSelectiveService() - we not start public boolean test(Person p) from this class (how it describe in text: "To use this class, you create a new instance of it and invoke the printPersons method:") and this method not in a constructor.
Can you please describe this Approach 3 more clearly, please?
Thanks.
</quote>
The method printPerson is an instance method of the class Person. It prints details about an instance of Person. The method printPersons (with an 's') is a static method that's part of the sample application RosterTest.
The parameter tester is an instance of CheckPerson, which is an interface that contains one method, test. However, you have to implement the interface CheckPerson by creating a new class that extends it.
The class CheckPersonEligibleForSelectiveService is a class that implements the interface CheckPerson.
The method printPersons takes two arguments, a List<Person> instance and a CheckPerson instance. We can use roster as the List<Person> instance. We can use an instance of CheckPersonEligibleForSelectiveService as the CheckPerson instance. To create an instance of CheckPersonEligibleForSelectiveService, we use the constructor new CheckPersonEligibleForSelectiveService().
Because this instance of CheckPersonEligibleForSelectiveService extends the instance CheckPerson, we can invoke the method CheckPersonEligibleForSelectiveService.test, which returns a boolean value.
Thanks for your comments regarding this section of the Lambda Expressions page. We'll definitely better explain what's going on in this section.
=========================================================
Subject: Mistake in code?
Date: October 25, 2013 6:49 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
As a result, the following method invocation is the same as when you invoked printPersons in Approach 3: Specify Search Criteria Code in a Local Class to obtain members who are eligible for Selective Service:
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
but Approach 3 is:
printPersons(
roster,
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
</quote>
Yes, that is definitely a typo. Thanks for noticing it!
===========================================================
Subject: Mistake in text?
Date: October 25, 2013 4:23 PM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
The following method retrieves the email address from each member contained in roster and then prints it:
processPersonsWithFunction(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
But as I can see - this method print only email of people "eligible for Selective Service", no?
And maybe this article may say some words about word mail in labda?
</quote>
Yes, you're correct. It only retrieves e-mail addresses of those who are eligible for Selective Service.
For email -> System.out.println(email), the use of the variable "email" is irrelevant. It could be e -> System.out.println(e) or even p -> System.out.println(p). Variable names in lambda expressions are like parameter names in methods.
=======================================================================
Subject: Different definitions of overloading
Date: Sat, 26 Oct 2013 13:50:47 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type.
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Overloaded methods are those that have the same name and belong to the same class, but have different parameter lists or return values
?
</quote>
Thanks for noticing this. The first statement you found about overloading is true; we'll verify with engineering as well.
==================================================================
Subject: One thing I can't understand...
Date: October 28, 2013 10:51 AM
<quote>
Hi, I am about this page:
However, like local and anonymous classes, a lambda expression can only access local variables and parameters of the enclosing block that are final or effectively final. For example, suppose that you add the following assignment statement immediately after the methodInFirstLevel definition statement:
void methodInFirstLevel(int x) {
x = 99;
// ...
}
Because of this assignment statement, the variable FirstLevel.x is not effectively final anymore. As a result, the Java compiler generates an error message similar to "local variables referenced from a lambda expression must be final or effectively final" where the lambda expression myBlock tries to access the FirstLevel.x variable:
System.out.println("x = " + x);
I can't understand why I can't make x = 99 - I think we just reassign to argument x new value (99), no? If this piece of article talk about FirstLevel.x - reassign must be FirstLevel.x = 99 - no?
For example, I write my test code:
public class Test {
int x = 0;
void testMethod(int x) {
x = 1;
System.out.println(x);
}
public static void main(String[] args) {
Test ob = new Test();
ob.testMethod(2);
}
}
In this case I can reassign argument x, if I want reassing field x - I can type this.x = something
I hope in next revision of this article you can describe this moment more clearly.
Thank you.
</quote>
This applies to variables that are reassigned outside a lambda expression, and the lambda expression uses it too. Consider this example:
public class Test {
int x = 0;
void testMethod(int x) {
x = 1;
java.util.function.Consumer<java.lang.Integer> myConsumer = (y) ->
{
System.out.println("Value of y: " + y);
System.out.println("Value of x: " + x);
};
myConsumer.accept(java.lang.Integer.valueOf(x));
}
public static void main(String[] args) {
Test ob = new Test();
ob.testMethod(2);
}
}
You would get this compiler error:
Test.java:12: error: local variables referenced from a lambda expression must be final or effectively final
System.out.println("Value of x: " + x);
^
If you remove the assignment x = 1 in testMethod, then the Test class compiles.
=======================================================================
Subject: Need of example
Date: Tue, 29 Oct 2013 10:58:06 +0300
<quote>
Hello, I am about this page:
This approach can potentially make your application brittle: Suppose that you upgrade your application and change the structure of the Person class such that it contains different member variables; perhaps the class records and measures ages with a different data type or algorithm. You would have to rewrite a lot of your API to accommodate this change.
I read again and again this piece of article and I can't understand - why this approach is brittle? Maybe in next version of this article will be better to write some code examples?
Thanks.
</quote>
OK, we'll consider adding an example. I think a definition of what brittleness is would improve this section too: the idea about the likelihood of an application breaking due to updates introduced by (for example) newer types of data.
=======================================================================
Subject: Re: Mistake in text or nor clearly described?
Date: Wed, 30 Oct 2013 14:21:31 +0300
<quote>
Sorry, now I understand that you talk about method processPersonsWithFunction, not about statements :)
30.10.2013, 14:11, "Vitaly Zdanevich" <zdanevich.vitaly@ya.ru>:
> Hi, I am about this page:
>
>> The Function<T,R> interface contains the method R apply(T t). The following method retrieves the data specified by the parameter mapper, and then performs an action on it specified by the parameter block
>
> As I can see, this text talk about generics interfaces as a parameters:
>
>> Function<Person, String> mapper,
>
>> Consumer<String> block)
>
> And what mean:
>
>> The following method retrieves the data specified by the parameter mapper, and then performs an action on it specified by the parameter block
>
> ...if I see two interfaces-arguments (with its methods, two methods for two interfaces), but not a one method that retrieve data and perform action?
>
> Maybe it mistake in text or more clearly description may help to understand this.
>
> Thank you.
</quote>
We hope that you understand the concept.
=======================================================================
Subject: Notice that the class PersonAgeComparator is a functional interface
Date: Fri, 1 Nov 2013 11:48:32 +0300
<quote>
Hi, I am about this page: http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
> Notice that the class PersonAgeComparator is a functional interface
What is that mean? How class can be of interface too?
</quote>
That's a typo; thanks for spotting it. The sentence should read:
Notice that the interface Comparator is a functional interface.
===================================================================
Subject: Not clearly understand in Method References
Date: November 4, 2013 6:53 AM
<quote>
Hi, I am about this page:
The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:
Its formal parameter list is copied from Comparator<Person>.compare, which is (Person, Person).
I don't understand - formal parameters copied from Comparator<Person>.compare? Not from the method compareByAge?
</quote>
Remember there's a difference between formal parameters (which are the types of objects that a method requires) and arguments (which are the actual objects that are used to invoke a method.
=======================================================================
Subject: Said is not clear: When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions
Date: Mon, 04 Nov 2013 17:11:27 +0300
<quote>
Hi, I am about this page:
Anonymous class: Use it if you need an instance of a class or a nonfunctional interface, fields, or additional methods.
Use anonymous class when I need instance of field?
</quote>
Perhaps a better wording would be, "if you need to declare fields or additional methods."
=======================================================================
Subject: Why this code have this?
Date: Thu, 17 Oct 2013 15:46:04 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html
Code on this link also work good without this:
InnerEvenIterator iterator = this.new InnerEvenIterator();
I newbie in Java and don't understand - why this code have this and why this example compile and run without this. Maybe other readers of this Java Tutorial will have the same questions.
Thank you.
</quote>
Thanks for pointing this out; the example on this page is quite old and it needs to be updated. As an FYI, Java SE 8 is introducing aggregate operations, which moves away from the iterator model:
http://docs.oracle.com/javase/tutorial/collections/streams/
=======================================================================
Subject: Mistake in text?
Date: October 22, 2013 7:40 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
This method invokes the method printPerson on each Person instance.
But printPerson() invoke only if (tester.test(p)), yes?..
</quote>
Yes, we'll clarify that printPerson is only invoked if tester.test(p) returns true.
=======================================================================
Subject: (No subject)
Date: October 23, 2013 6:35 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
You can specify the action performed on each Person instance with a lambda expression. Remember, to use a lambda expression, you need to implement a functional interface. In this case, you need a functional interface that contains a method that takes one argument (an object of type Person) and returns void. The Consumer<T> interface contains the method void accept(T t). The following method replaces the invocation p.printPerson() with an instance of Consumer<Person> that invokes the method accept:
public static void processPersons(
List<Person> roster,
Predicate<Person> tester,
Consumer<Person> block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
I read this again and again but can't clearly understand this piece of text. Why we need method that return void - I think that we need true or false for testing people for entering for search criteria, no? I just learn Java and maybe for future readers you can explain idea behind this piece of article more simple and clearly?
Thank you.
</quote>
We need to clarify this paragraph. It's not about tester but about block (what to do with each Person instance, which is to print something out in this example). The tester lambda expression was discussed in the previous section, Approach 6: Use Standard Functional Interfaces with Lambda Expressions.
=======================================================================
Subject: Mistake in code?
Date: Thu, 24 Oct 2013 00:47:08 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/examples/Person.java
Here we have this piece of code:
public int getAge() {
return birthday
.until(IsoChronology.INSTANCE.dateNow())
.getYears();
}
and this:
public LocalDate getBirthday() {
return birthday;
}
1) Return birthday two times?
2) Return birthday in method getAge?
</quote>
The field birthday is of type LocalDate, which is part of the new Date-Time API:
http://docs.oracle.com/javase/tutorial/datetime/index.html
The method getBirthday is a getter method. The sample code uses getAge, which returns an int, to help it compare ages.
==================================================================
Subject: Not clear piece of article: Lambda Expressions: Approach 3
Date: October 24, 2013 11:00 AM
<quote>
Hi, I am about this page.
Approach 3: Specify Search Criteria Code in a Local Class - this part of article is not very clear:
Here we have:
public static void printPersons(
List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
But below:
printPersons(roster, new CheckPersonEligibleForSelectiveService());
Why this call have arguments, but in call above - p.printPerson(); - we don't have arguments?
And what is tester? In Approach 3 this word (class?) not described :(
And when we do new CheckPersonEligibleForSelectiveService() - we not start public boolean test(Person p) from this class (how it describe in text: "To use this class, you create a new instance of it and invoke the printPersons method:") and this method not in a constructor.
Can you please describe this Approach 3 more clearly, please?
Thanks.
</quote>
The method printPerson is an instance method of the class Person. It prints details about an instance of Person. The method printPersons (with an 's') is a static method that's part of the sample application RosterTest.
The parameter tester is an instance of CheckPerson, which is an interface that contains one method, test. However, you have to implement the interface CheckPerson by creating a new class that extends it.
The class CheckPersonEligibleForSelectiveService is a class that implements the interface CheckPerson.
The method printPersons takes two arguments, a List<Person> instance and a CheckPerson instance. We can use roster as the List<Person> instance. We can use an instance of CheckPersonEligibleForSelectiveService as the CheckPerson instance. To create an instance of CheckPersonEligibleForSelectiveService, we use the constructor new CheckPersonEligibleForSelectiveService().
Because this instance of CheckPersonEligibleForSelectiveService extends the instance CheckPerson, we can invoke the method CheckPersonEligibleForSelectiveService.test, which returns a boolean value.
Thanks for your comments regarding this section of the Lambda Expressions page. We'll definitely better explain what's going on in this section.
=========================================================
Subject: Mistake in code?
Date: October 25, 2013 6:49 AM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
As a result, the following method invocation is the same as when you invoked printPersons in Approach 3: Specify Search Criteria Code in a Local Class to obtain members who are eligible for Selective Service:
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
but Approach 3 is:
printPersons(
roster,
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
</quote>
Yes, that is definitely a typo. Thanks for noticing it!
===========================================================
Subject: Mistake in text?
Date: October 25, 2013 4:23 PM
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
The following method retrieves the email address from each member contained in roster and then prints it:
processPersonsWithFunction(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
But as I can see - this method print only email of people "eligible for Selective Service", no?
And maybe this article may say some words about word mail in labda?
</quote>
Yes, you're correct. It only retrieves e-mail addresses of those who are eligible for Selective Service.
For email -> System.out.println(email), the use of the variable "email" is irrelevant. It could be e -> System.out.println(e) or even p -> System.out.println(p). Variable names in lambda expressions are like parameter names in methods.
=======================================================================
Subject: Different definitions of overloading
Date: Sat, 26 Oct 2013 13:50:47 +0300
<quote>
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type.
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Overloaded methods are those that have the same name and belong to the same class, but have different parameter lists or return values
?
</quote>
Thanks for noticing this. The first statement you found about overloading is true; we'll verify with engineering as well.
==================================================================
Subject: One thing I can't understand...
Date: October 28, 2013 10:51 AM
<quote>
Hi, I am about this page:
However, like local and anonymous classes, a lambda expression can only access local variables and parameters of the enclosing block that are final or effectively final. For example, suppose that you add the following assignment statement immediately after the methodInFirstLevel definition statement:
void methodInFirstLevel(int x) {
x = 99;
// ...
}
Because of this assignment statement, the variable FirstLevel.x is not effectively final anymore. As a result, the Java compiler generates an error message similar to "local variables referenced from a lambda expression must be final or effectively final" where the lambda expression myBlock tries to access the FirstLevel.x variable:
System.out.println("x = " + x);
I can't understand why I can't make x = 99 - I think we just reassign to argument x new value (99), no? If this piece of article talk about FirstLevel.x - reassign must be FirstLevel.x = 99 - no?
For example, I write my test code:
public class Test {
int x = 0;
void testMethod(int x) {
x = 1;
System.out.println(x);
}
public static void main(String[] args) {
Test ob = new Test();
ob.testMethod(2);
}
}
In this case I can reassign argument x, if I want reassing field x - I can type this.x = something
I hope in next revision of this article you can describe this moment more clearly.
Thank you.
</quote>
This applies to variables that are reassigned outside a lambda expression, and the lambda expression uses it too. Consider this example:
public class Test {
int x = 0;
void testMethod(int x) {
x = 1;
java.util.function.Consumer<java.lang.Integer> myConsumer = (y) ->
{
System.out.println("Value of y: " + y);
System.out.println("Value of x: " + x);
};
myConsumer.accept(java.lang.Integer.valueOf(x));
}
public static void main(String[] args) {
Test ob = new Test();
ob.testMethod(2);
}
}
You would get this compiler error:
Test.java:12: error: local variables referenced from a lambda expression must be final or effectively final
System.out.println("Value of x: " + x);
^
If you remove the assignment x = 1 in testMethod, then the Test class compiles.
=======================================================================
Subject: Need of example
Date: Tue, 29 Oct 2013 10:58:06 +0300
<quote>
Hello, I am about this page:
This approach can potentially make your application brittle: Suppose that you upgrade your application and change the structure of the Person class such that it contains different member variables; perhaps the class records and measures ages with a different data type or algorithm. You would have to rewrite a lot of your API to accommodate this change.
I read again and again this piece of article and I can't understand - why this approach is brittle? Maybe in next version of this article will be better to write some code examples?
Thanks.
</quote>
OK, we'll consider adding an example. I think a definition of what brittleness is would improve this section too: the idea about the likelihood of an application breaking due to updates introduced by (for example) newer types of data.
=======================================================================
Subject: Re: Mistake in text or nor clearly described?
Date: Wed, 30 Oct 2013 14:21:31 +0300
<quote>
Sorry, now I understand that you talk about method processPersonsWithFunction, not about statements :)
30.10.2013, 14:11, "Vitaly Zdanevich" <zdanevich.vitaly@ya.ru>:
> Hi, I am about this page:
>
>> The Function<T,R> interface contains the method R apply(T t). The following method retrieves the data specified by the parameter mapper, and then performs an action on it specified by the parameter block
>
> As I can see, this text talk about generics interfaces as a parameters:
>
>> Function<Person, String> mapper,
>
>> Consumer<String> block)
>
> And what mean:
>
>> The following method retrieves the data specified by the parameter mapper, and then performs an action on it specified by the parameter block
>
> ...if I see two interfaces-arguments (with its methods, two methods for two interfaces), but not a one method that retrieve data and perform action?
>
> Maybe it mistake in text or more clearly description may help to understand this.
>
> Thank you.
</quote>
We hope that you understand the concept.
=======================================================================
Subject: Notice that the class PersonAgeComparator is a functional interface
Date: Fri, 1 Nov 2013 11:48:32 +0300
<quote>
Hi, I am about this page: http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
> Notice that the class PersonAgeComparator is a functional interface
What is that mean? How class can be of interface too?
</quote>
That's a typo; thanks for spotting it. The sentence should read:
Notice that the interface Comparator is a functional interface.
===================================================================
Subject: Not clearly understand in Method References
Date: November 4, 2013 6:53 AM
<quote>
Hi, I am about this page:
The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:
Its formal parameter list is copied from Comparator<Person>.compare, which is (Person, Person).
I don't understand - formal parameters copied from Comparator<Person>.compare? Not from the method compareByAge?
</quote>
Remember there's a difference between formal parameters (which are the types of objects that a method requires) and arguments (which are the actual objects that are used to invoke a method.
=======================================================================
Subject: Said is not clear: When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions
Date: Mon, 04 Nov 2013 17:11:27 +0300
<quote>
Hi, I am about this page:
Anonymous class: Use it if you need an instance of a class or a nonfunctional interface, fields, or additional methods.
Use anonymous class when I need instance of field?
</quote>
Perhaps a better wording would be, "if you need to declare fields or additional methods."