This question already has answers here:
Java default values confusion, why none for function scoped variables? [duplicate]
(3 answers)
Closed 8 years ago.
This is fine...
public class someClass {
private Set<Element> pre;
public void someMethod() {
pre.add(new Element());
}
}
But this isn't...
public class someClass {
public void someMethod() {
Set<Element> pre;
pre.add(new Element());
}
}
What's the correct syntax for the latter case without just turning it into the former?
In both cases you are missing the initialization of the Set, but in the first case it's initialized to null by default, so the code will compile, but will throw a NullPointerException when you try to add something to the Set. In the second case, the code won't even compile, since local variables must be assigned a value before being accessed.
You should fix both examples to
private Set<Element> pre = new HashSet<Element>();
and
Set<Element> pre = new HashSet<Element>();
Of course, in the second example, the Set is local to someMethod(), so there's no point in this code (you are creating a local Set which you are never using).
HashSet is one implementation of Set you can use. There are others. And if your know in advance the number of distinct elements that would be added to the Set, you can specify that number when constructing the Set. It would improve the Set's performance, since it wouldn't need to be re-sized.
private Set<Element> pre = new HashSet<Element>(someInitialSize);
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 4 months ago.
I want to move some special object in the list to the bottom of it.
I tried to used below code to implement it but it shows last assignment is never been used...
I have walkaround but I really want to know why my code is wrong?
After the method proceed the list I passed in, it still the old sequence. No impact...
private void moveNullBrokerToEnd(List<Broker> brokers) {
if (brokers != null) {
List<Broker> nullTypeBrokers = new ArrayList<>();
List<Broker> commonBrokers = new ArrayList<>();
for (Broker broker : brokers) {
if (broker.getMemberType()==null) {
nullTypeBrokers.add(broker);
} else {
commonBrokers.add(broker);
}
}
brokers = ListUtils.union(commonBrokers, nullTypeBrokers);
}
}
You are assigning new Object to brokers reference. brokers is a reference to this list Object, but when you assign new object to it, it's not visible outside of the function. You could say that it's pointing to a new object from now on.
You need to return brokers as new list (recommended) or clear the list then add all values from union.
Example:
brokers.clear();
brokers.addAll(ListUtils.union(commonBrokers, nullTypeBrokers))
But this has many drawbacks:
violates conventions for clean code
will not work for null reference.
You might change original list - mutating is wrong
You can use sort function here instead:
#Test
public void setNullsFirst() {
List<Broker> brokers = List.of(
new Broker("1."),
new Broker(null),
new Broker("2."),
new Broker(null)
);
System.out.println(moveNullBrokerToEnd(brokers));
}
private List<Broker> moveNullBrokerToEnd(List<Broker> brokers) {
return Optional.ofNullable(brokers).orElseGet(Collections::emptyList)
.stream()
.sorted(Comparator.comparing(broker->broker.memberType==null?-1:0))
.toList();
}
The results are:
[Broker(memberType=null), Broker(memberType=null), Broker(memberType=1.), Broker(memberType=2)]
Parameters of methods are passed by-value (that means, the reference to objects are passed by value). So when you modify the reference in the brokers parameter (the object it is pointing to) this change only has impact inside the method.
The caller of the method will not notice any change.
And in your method, you don't use the brokers parameter after the re-assignment and so you don't use the actual result of the ListUtils.union call.
This question already has answers here:
What is variable shadowing used for in a Java class?
(5 answers)
Closed 8 years ago.
I was reading a book and came across the term Shadow Variables in Java but there was no description for it. Eventually what are these variables used for and how are they implemented?
Instead of providing my own description i may ask you to read about it for example here: http://en.wikipedia.org/wiki/Variable_shadowing. Once you understood the shadowing of variables i recommend you proceed reading about overlaying/ shadowed methods and visibility in general to get a full understanding of such terms.
Actually since the question was asked in Terms of Java here is a mini-example:
public class Shadow {
private int myIntVar = 0;
public void shadowTheVar(){
// since it has the same name as above object instance field, it shadows above
// field inside this method
int myIntVar = 5;
// If we simply refer to 'myIntVar' the one of this method is found
// (shadowing a seond one with the same name)
System.out.println(myIntVar);
// If we want to refer to the shadowed myIntVar from this class we need to
// refer to it like this:
System.out.println(this.myIntVar);
}
public static void main(String[] args){
new Shadow().shadowTheVar();
}
}
This question already has answers here:
Default constructor vs. inline field initialization
(5 answers)
Closed 3 years ago.
I have a class like:
public class TemplateFileResponse {
private String path;
private List<FileView> children;
}
I want to create an instance and set children is empty array. so what is the best way to do it?
You can create an empty list with the new operator:
public class TemplateFileResponse {
private String path;
private List<FileView> children = new ArrayList<>();
}
You may also want to initialize the path field, either in a constructor or inline, because otherwise it will be initialized to null by default.
I suggest that you read a tutorial about Java classes, constructors, methods, and instantiating objects to understand how all of this works.
This question already has answers here:
Variable used in lambda expression should be final or effectively final
(9 answers)
Closed 4 years ago.
This question is already asked. But today I found something odd. For the following code:-
public static List<EsbBucketInstanceDefinition> convertBucketDefinitionList(List<BucketInstanceDefinitionV1> bucketInstanceDefinitionV1List) {
List<EsbBucketInstanceDefinition> response = new ArrayList<>();
List<EsbBucketInstanceDefinition> finalResponse = new ArrayList<>();
bucketInstanceDefinitionV1List.stream().forEach(e -> {
EsbBucketInstanceDefinition esbBucketInstanceDefinition = new EsbBucketInstanceDefinition();
esbBucketInstanceDefinition.setInstanceType(e.getInstanceType());
esbBucketInstanceDefinition.setReportingGroup(e.getReportingGroup());
esbBucketInstanceDefinition.setSliceVolume(e.getSliceVolume());
esbBucketInstanceDefinition.setCounterName(e.getCounterName());
esbBucketInstanceDefinition.setSubscriberGroupId(e.getSubscriberGroupId());
// response.add(esbBucketInstanceDefinition); compiler error variable used in lambda should be final or effective final
finalResponse.add(esbBucketInstanceDefinition);
});
return finalResponse;
}
For this works fine. Looks like only variable name finalResponse is working. How and why? Is it valid to do?
References may only be made to (effectively) final variables from within a lambda.
The reference held by finalResponse in effectively final, because it never changes. Note that changing the reference means assigning a new value to it, eg
finalResponse = someOtherList;
Changing the state of the object referred to (eg adding items to the list referred to by finalResponse) is irrelevant to what the value held by the variable finalResponse, ie
finalResponse.add(something);
Does not change the variable finalResponse; it only changes the object to which finalResponse refers.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Should I initialize variable within constructor or outside constructor
I was wondering, which is a better practice and why. Should I initialize class fields upon declaration, or should I do it in the constructor? Given that it's a simple one-line initialization.
class Dude
{
String name = "El duderino";
Dude() {
// irrelevant code
}
}
vs.
class Dude
{
String name;
Dude() {
name = "El duderino";
// irrelevant code
}
}
Edit: I am aware of the situations where one of the styles would be preferred over the other like in the case of executing initializer code that might throw an exception. What I'm talking about here are cases when both styles are absolutely equivalent. Both ways would accomplish the same task. Which should I use then?
If the member can only be set via an accessor (a "setter" method), I prefer the first style. It provides a hint that the initialized value is the default upon construction.
If the member can be specified during construction, I generally pass the default value to an appropriate constructor from constructor with fewer parameters. For example,
final class Dude {
private final String name;
Dude() {
this("El Duderino");
}
Dude(String name) {
this.name = name;
}
}
The first one is used usually to initialize static variable and should be used only for that purpose.
In this case, you should use the second method.
Please correct me if I am wrong.
It is best to declare variables inside the constructor for the sake of consistency. A variable may require something like a loop or an if-else statement to initialize it, which can not be done in the declaration without placing the operation inside of a method.
The exception to this rule is static variables, which should be declared outside of the constructor.
Single-line declarations cannot contain complex initialization logic.
If you initialize a variable as:
class AnotherClass
{
MyClass anObject = new MyClass(); //MyClass() throws a checked exception.
}
then you'll find that you cannot provide the initial value in the single line. You'll need to place such code in a block, that quite obviously goes inside a constructor (or in a non-static initialization block):
Using a constructor:
class AnotherClass
{
MyClass anObject;
AnotherClass()
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
Using a initialization block:
class AnotherClass
{
MyClass anObject;
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
I find that the latter makes for less understandable code, as the declaration and initialization are separated from each other, and the initialization does not occur in a constructor coded by the developer (although there is no difference at runtime).
The same goes for other complex routines involved in initialization of fields. For example, if you intend to initialize an Array or a Collection and set the contents of the array/collection to some default value, then you should do so inside a constructor:
class AnotherClass
{
Integer[] integers;
AnotherClass()
{
this.integers = new Integer[10];
for(Integer integer: integers)
{
integer = Integer.MIN_VALUE;
}
}
}