Related
down bellow you can see two example methods, which are structured in the same way, but have to work with completely different integers.
You can guess if the code gets longer, it is pretty anoying to have a second long method which is doing the same.
Do you have any idea, how i can combine those two methods without using "if" or "switch" statements at every spot?
Thanks for your help
public List<> firstTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 1){
return blabla.getChildren().subList(2, blabla.getChildren().size());
}
}
return null;
}
And:
public List<> secondTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 4){
return blabla.getChildren().subList(0, 2);
}
}
return null;
}
Attempting to isolate common ground from 2 or more places into its own Helper method is not a good idea if you're just looking at what the code does without any context.
The right approach is first to define what you're actually isolating. It's not so much about the how (the fact that these methods look vaguely similar suggests that the how is the same, yes), but the why. What do these methods attempt to accomplish?
Usually, the why is also mostly the same. Rarely, the why is completely different, and the fact that the methods look similar is a pure coincidence.
Here's a key takeaway: If the why is completely different but the methods look somewhat similar, you do not want to turn them into a single method. DRY is a rule of thumb, not a commandment!
Thus, your question isn't directly answerable, because the 2 snippets are so abstractly named (blabla isn't all that informative), it's not possible to determine with the little context the question provides what the why might be.
Thus, answer the why question first, and usually the strategy on making a single method that can cater to both snippets here becomes trivial.
Here is an example answer: If list is 'valid', return the first, or last, X elements inside it. Validity is defined as follows: The list is not null, and contains at least Z entries. Otherwise, return null.
That's still pretty vague, and dangerously close to a 'how', but it sounds like it might describe what you have here.
An even better answer would be: blabla represents a family; determine the subset of children who are eligible for inheriting the property.
The reason you want this is twofold:
It makes it much easier to describe a method. A method that seems to do a few completely unrelated things and is incapable of describing the rhyme or reason of any of it cannot be understood without reading the whole thing through, which takes a long time and is error-prone. A large part of why you want methods in the first place is to let the programmer (the human) abstract ideas away. Instead of remembering what these 45 lines do, all you need to remember is 'fetch the eligible kids'.
Code changes over time. Bugs are found and need fixing. External influences change around you (APIs change, libraries change, standards change). Feature requests are a thing. Without the why part it is likely that one of the callers of this method grows needs that this method cannot provide, and then the 'easiest' (but not best!) solution is to just add the functionality to this method. The method will eventually grow into a 20 page monstrosity doing completely unrelated things, and having 50 parameters. To guard against this growth, define what the purpose of this method is in a way that is unlikely to spiral into 'read this book to understand what all this method is supposed to do'.
Thus, your question is not really answerable, as the 2 snippets do not make it obvious what the common thread might be, here.
Why do these methods abuse null? You seem to think null means empty list. It does not. Empty list means empty list. Shouldn't this be returning e.g. List.of instead of null? Once you fix that up, this method appears to simply be: "Give me a sublist consisting of everything except the first two elements. If the list is smaller than that or null, return an empty list", which is starting to move away from the 'how' and slowly towards a 'what' and 'why'. There are only 2 parameters to this generalized concept: The list, and the # of items from the start that need to be omitted.
The second snippet, on the other hand, makes no sense. Why return the first 3 elements, but only if the list has 5 or more items in it? What's the link between 3 and 5? If the answer is: "Nothing, it's a parameter", then this conundrum has far more parameters than the first snippet, and we see that whilst the code looks perhaps similar, once you start describing the why/what instead of the how, these two jobs aren't similar at all, and trying to shoehorn these 2 unrelated jobs into a single method is just going to lead to bad code now, and worse code later on as changes occur.
Let's say instead that this last snippet is trying to return all elements except the X elements at the end, returning an empty list if there are fewer than X. This matches much better with the first snippet (which does the same thing, except replace 'at the end' with 'at the start'). Then you could write:
// document somewhere that `blabla.getChildren()` is guaranteed to be sorted by age.
/** Returns the {#code numEldest} children. */
public List<Child> getEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, true);
}
/** Returns all children except the {#code numEldest} ones. */
public List<Child> getAllButEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, false);
}
private List<Child> getChildren(int numEldest, boolean include) {
if (blabla == null) return List.of();
List<Child> children = blabla.getChildren();
if (numEldest >= children.size()) return include ? children : List.of();
int startIdx = include ? 0 : numEldest;
int endIdx = include ? numEldest : children.size();
return children.subList(startIdx, endIdx);
}
Note a few stylistic tricks here:
boolean parameters are bad, because why would you know 'true' matches up with 'I want the eldest' and 'false' matches up with 'I want the youngest'? Names are good. This snippet has 2 methods that make very clear what they do, by using names.
That 'when extracting common ground, define the why, not the how' is a hierarchical idea - apply it all the way down, and as you get further away from the thousand-mile view, the what and how become more and more technical. That's okay. The more down to the details you get, the more private things should be.
By having defined what this all actually means, note that the behaviour is subtly different: If you ask for the 5 eldest children and there are only 4 children, this returns those 4 children instead of null. That shows off some of the power of defining the 'why': Now it's a consistent idea. Returning all 4 when you ask for 'give me the 5 eldest', is no doubt 90%+ of all those who get near this code would assume happens.
Preconditions, such as what comprises sane inputs, should always be checked. Here, we check if the numEldest param is negative and just crash out, as that makes no sense. Checks should be as early as they can reasonably be made: That way the stack traces are more useful.
You can pass objects that encapsulate the desired behavior differences at various points in your method. Often you can use a predefined interface for behavior encapsulation (Runnable, Callable, Predicate, etc.) or you may need to define your own.
public List<> testMethod(Predicate<BlaBlaType> test,
Function<BlaBlaType, List<>> extractor)
{
if(blabla != null){
if(test.test(blabla)){
return extractor.apply(blabla);
}
}
return null;
}
You could then call it with a couple of lambdas:
testMethod(
blabla -> blabla.getChildren().size() > 1,
blabla -> blabla.getChildren().subList(2, blabla.getChildren().size())
);
testMethod(
blabla -> blabla.getChildren().size() > 4,
blabla -> blabla.getChildren().subList(0, 2)
);
Here is one approach. Pass a named boolean to indicate which version you want. This also allows the list of children to be retrieved independent of the return. For lack of more meaningful names I choose START and END to indicate which parts of the list to return.
static boolean START = true;
static boolean END = false;
public List<Children> TestMethod(boolean type) {
if (blabla != null) {
List<Children> list = blabla.getChildren();
int size = list.size();
return START ?
(size > 1 ? list.subList(0, 2) : null) :
(size > 4 ? list.subList(2, size) :
null);
}
return null;
}
I've seen code as below:
if (!substanceList.isEmpty() && (substanceList.size() > 0))
{
substanceText = createAmountText(substanceList);
}
Would the following be a valid refactor?
if (!substanceList.isEmpty())
{
substanceText = createAmountText(substanceList);
}
I would be grateful for an explanation of the above code and whether the second version may cause errors?
If in doubt, read the Javadoc:
Collection.isEmpty():
Returns true if this collection contains no elements.
Collection.size():
Returns the number of elements in this collection
So, assuming the collection is implemented correctly:
collection.isEmpty() <=> collection.size() == 0
Or, conversely:
!collection.isEmpty() <=> collection.size() != 0
Since the number of elements should only be positive, this means that:
!collection.isEmpty() <=> collection.size() > 0
So yes, the two forms are equivalent.
Caveat: actually, they're only equivalent if your collection isn't being modified from another thread at the same time.
This:
!substanceList.isEmpty() && (substanceList.size() > 0)
is equivalent to, by the logic I present above:
!substanceList.isEmpty() && !substanceList.isEmpty()
You can only simplify this to
!substanceList.isEmpty()
if you can guarantee that its value doesn't change in between evaluations of substanceList.isEmpty().
Practically, it is unlikely that you need to care about the difference between these cases, at least at this point in the code. You might need to care about the list being changed in another thread, however, if it can become empty before (or while) executing createAmountText. But that's not something that was introduced by this refactoring.
TL;DR: using if (!substanceList.isEmpty()) { does practically the same thing, and is clearer to read.
The only difference between the first and the second approach is that the first approach performs a redundant check. nothing else.
Thus, you'd rather avoid the redundant check and go with the second approach.
Actually, you can read the source code downloaded in the JDK:
/**
* Returns <tt>true</tt> if this list contains no elements.
*
* #return <tt>true</tt> if this list contains no elements
*/
public boolean isEmpty() {
return size == 0;
}
I think that this settles all the queries.
Implementation of isEmpty() in AbstractCollection is as follows:
public boolean isEmpty() {
return size() == 0;
}
So you can safely assume that !list.isEmpty() is equivalent to list.size() > 0.
As for "what is better code", if you want to check if the list is empty or not, isEmpty() is definitely more expressive.
Subclasses might also override isEmpty() from AbstractCollection and implement in more efficient manner than size() == 0. So (purely theoretically) isEmpty() might be more efficient.
The javadocs for Collection.size() and Collection.isEmpty() say:
boolean isEmpty()
Returns true if this collection contains no elements.
int size()
Returns the number of elements in this collection
Since "contains no elements" implies that the number of elements in the collection is zero, it follows that list.isEmpty() and list.size() == 0 will evaluate to the same value.
I want to some explanation of above code
The second version is correct. The first version looks like it was written either by an automatic code generator, or a programmer who doesn't really understand Java. There is no good reason to write the code that way.
(Note: if some other thread could be concurrently modifying the list, then both versions are problematic unless there is proper synchronization. If the list operations are not synchronized then may be memory hazards. But in the first version, there is also the possibility of a race condition ... where the list appears be empty and have a non-zero size!)
and want to know second way may be caused some error.
It won't.
Incidentally list.isEmpty() is preferable to list.size() == 0 for a couple of reasons:
It is more concise (fewer characters).
It expresses the intent of your code more precisely.
It may be more efficient. Some collection implementations may need to count the elements in the collection to compute the size. That may be an O(N) operation, and could other undesirable effects. For example, if a collection is a lazy list that only gets reified as you iterate the elements, then calling size() may result in excessive memory use.
Yes, it can be refactored as you did. The issue with both approaches is that you would do the check every time you want to call the method createAmountText on a List. This means you would be repeating the logic, a better way would be to use DRY (don't Repeat Yourself) principle and factor these checks into your method.
So your method's body should encapsulated by this check.
It should look like:
<access modifier> String createAmountText(List substanceList){
if(substanceList != null && !substanceList.isEmpty()){
<The methods logic>
}
return null;
}
Sure - the two methods can be used to express the same thing.
But worth adding here: going for size() > 0 is somehow a more direct violation of the Tell, don't ask principle: you access an "implementation detail", to then make a decision based on that.
In that sense, isEmpty() should be your preferred choice here!
Of course, you are still violating TDA when using isEmpty() - because you are again fetching status from some object to then make a decision on it.
So the really best choice would be to write code that doesn't need at all to make such a query to internal state of your collection to then drive decisions on it. Instead, simply make sure that createAmountText() properly deals with you passing in an empty list! Why should users of this list, or of that method need to care whether the list is empty or not?!
Long story short: maybe that is "over thinking" here - but again: not using these methods would lead you to write less code! And that is always an indication of a good idea.
So, I have this code, which is just the way I solved an exercise that was given to me, which consisted of creating a recursive function that received a number, and then gave you the sum of 1, all the numbers in between, and your number. I know I made it sound confusing, but here's an example:
If I inserted the number 5, then the returned value would have to be 15, because: 1+2+3+4+5 = 15.
public class Exercise {
public static void main(String[] args) {
int returnedValue = addNumbers(6);
System.out.print(returnedValue);
}
public static int addNumbers(int value) {
if (value == 1) return value;
return value = value + addNumbers(value-1);
}
}
Technically speaking, my code works just fine, but I still don't get why Eclipse made me write two returns, that's all I would like to know.
Is there a way I could only write "return" once?
Sure, you can write it with just one return:
public static int addNumbers(int value) {
if (value > 1) {
value += addNumbers(value - 1);
}
return value;
}
As you can see, it's done by having some variable retain the running result until you get to the end. In this case I was able to do it in-place in value, in other cases you may need to create a local variable, but the idea of storing your intermediate result somewhere until you get to the return point is a general one.
There should be two returns. Your first return says
if at 1: stop recurstion
and the second one says
continue recursion by returning my value plus computing the value less than me
You could combine them by using a ternary:
return value == 1 ? value : value + addNumbers(value - 1)
But it is not as readable.
Recursive funtions like
Fibbonacci's sequence
Fractals
Etc.
Use themselves multiple times because they contain themselves.
Feel free to correct me if I'm wrong, but I don't think there is a way to eliminate one of those returns unless you decide to put a variable outside of the method or change the method from being recursive.
In java, a method that returns a value, MUST return a value at some point, no matter what code inside of it does. The reason eclipse requires you to add the second return, is because the first return is only run if your if statement evaluates to true. If you didn't have the second return, and that if statement did not end up being true, java would not be able to leave that method, and would have no idea what to do, thus, eclipse will require you to add a return statement after that if statement.
These types of errors are called checked errors or compile time errors. This means that eclipse literally can not convert your code into a runnable file, because it does not know how; there is a syntax error, or you are missing a return, etc.
Recursive functions always have at least 2 paths, the normal ones that will recurse and the "end" paths that just return (Usually a constant).
You could, however, do something like this:
public static int addNumbers(int value) {
if (value != 1)
value = value + addNumbers(value-1);
return value;
}
But I can't say I think it's much better (Some people get as annoyed at modifying parameters as they do at multiple returns). You could, of course, create a new variable and set it to one value or the other, but then someone would get upset because you used too many lines of code and an unnecessary variable. Welcome to programming :) Your original code is probably as good as you're likely to get.
As for why "Eclipse" did that to you, it's actually Java--Java is better than most languages at making sure you didn't do something clearly wrong as soon as possible (In this case while you are typing instead of waiting for you to compile). It detected that one branch of your if returned a value and the other did not--which is clearly wrong.
Java is also very explicit forcing you to use a "return" statement where another language might let you get away with less. In Groovy You'd be tempted to eliminate the return and write something like:
def addNumbers(value){value + (value-1?0:addNumbers(value-1))}
just for fun but I certainly wouldn't call THAT more readable! Java just figures it's better to force you to be explicit in most cases.
From the wikipedia on recursion:
In mathematics and computer science, a class of objects or methods
exhibit recursive behavior when they can be defined by two properties:
A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer
A set of rules that reduce all other cases toward the base case
There are two returns because you have to handle the two cases above. In your example:
The base case is value == 1.
The case to reduce all other cases toward the base case is value + addNumbers(value-1);.
Source: https://en.wikipedia.org/wiki/Recursion#Formal_definitions
Of course there are other ways to write this, including some that do not require multiple returns, but in general multiple returns are a clear and normal way to express recursion because of the way recursion naturally falls into multiple cases.
Like the robots of Asimov, all recursive algorithms must obey three important laws:
A recursive algorithm must have a base case.
A recursive algorithm must change its state and move toward the base case.
A recursive algorithm must call itself, recursively.
Your if (value == 1) return value; return statement is the base case. That's when the recursion(calling itself) stops. When a function call happen, the compiler pushes the current state to stack then make the call. So, when that call has returned some value, it pulls the value from stack, makes calculation and return the result to upper level. That's why the other return statement is for.
Think of this like breaking up your problem:
addNumbers(3) = 3 + addNumbers(2) (this is returned by second one)
-> 2 + addNumbers(1) (this is returned by second one)
-> 1 (this is returned by base case)
I find that I often make a recursive call just to reorder arguments.
For example, here's my solution for endOther from codingbat.com:
Given two strings, return true if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be "case sensitive"). Note: str.toLowerCase() returns the lowercase version of a string.
public boolean endOther(String a, String b) {
return a.length() < b.length() ? endOther(b, a)
: a.toLowerCase().endsWith(b.toLowerCase());
}
I'm very comfortable with recursions, but I can certainly understand why some perhaps would object to it.
There are two obvious alternatives to this recursion technique:
Swap a and b traditionally
public boolean endOther(String a, String b) {
if (a.length() < b.length()) {
String t = a;
a = b;
b = t;
}
return a.toLowerCase().endsWith(b.toLowerCase());
}
Not convenient in a language like Java that doesn't pass by reference
Lots of code just to do a simple operation
An extra if statement breaks the "flow"
Repeat code
public boolean endOther(String a, String b) {
return (a.length() < b.length())
? b.toLowerCase().endsWith(a.toLowerCase())
: a.toLowerCase().endsWith(b.toLowerCase());
}
Explicit symmetry may be a nice thing (or not?)
Bad idea unless the repeated code is very simple
...though in this case you can get rid of the ternary and just || the two expressions
So my questions are:
Is there a name for these 3 techniques? (Are there more?)
Is there a name for what they achieve? (e.g. "parameter normalization", perhaps?)
Are there official recommendations on which technique to use (when)?
What are other pros/cons that I may have missed?
Another example
To focus the discussion more on the technique rather than the particular codingbat problem, here's another example where I feel that the recursion is much more elegant than a bunch of if-else's, swaps, or repetitive code.
// sorts 3 values and return as array
static int[] sort3(int a, int b, int c) {
return
(a > b) ? sort3(b, a, c) :
(b > c) ? sort3(a, c, b) :
new int[] { a, b, c };
}
Recursion and ternary operators don't bother me as much as it bothers some people; I honestly believe the above code is the best pure Java solution one can possibly write. Feel free to show me otherwise.
Let’s first establish that code duplication is usually a bad idea.
So whatever solution we take, the logic of the method should only be written once, and we need a means of swapping the arguments around that does not interfere with the logic.
I see three general solutions to that:
Your first recursion (either using if or the conditional operator).
swap – which, in Java, is a problem, but might be appropriate in other languages.
Two separate methods (as in #Ha’s solution) where one acts as the implementation of the logic and the other as the interface, in this case to sort out the parameters.
I don’t know which of these solutions is objectively the best. However, I have noticed that there are certain algorithms for which (1) is generally accepted as the idiomatic solution, e.g. Euklid’s algorithm for calculating the GCD of two numbers.
I am generally averse to the swap solution (2) since it adds an extra call which doesn’t really do anything in connection with the algorithm. Now, technically this isn’t a problem – I doubt that it would be less efficient than (1) or (3) using any decent compiler. But it adds a mental speed-bump.
Solution (3) strikes me as over-engineered although I cannot think of any criticism except that it’s more text to read. Generally, I don’t like the extra indirection introduced by any method suffixed with “Impl”.
In conclusion, I would probably prefer (1) for most cases although I have in fact used (3) in similar circumstances.
Another +1 for "In any case, my recommendation would be to do as little in each statement as possible. The more things that you do in a single statement, the more confusing it will be for others who need to maintain your code."
Sorry but your code:
// sorts 3 values and return as array
static int[] sort3(int a, int b, int c) {
return
(a > b) ? sort3(b, a, c) :
(b > c) ? sort3(a, c, b) :
new int[] { a, b, c };
}
It's perhaps for you the best "pure java code", but for me it's the worst... unreadable code, if we don't have the method or the comment we just can't know at first sight what it's doing...
Hard to read code should only be used when high performances are needed (but anyway many performances problems are due to bad architecture...). If you HAVE TO write such code, the less you can do is to make a good javadoc and unit tests... we developper often don't care about implementation of such methods if we just have to use it, and not to rework it... but since the first sight doesn't tell us what is does, we can have to trust it works like we expect it does and we can loose time...
Recursive methods are ok when it's a short method, but i think a recursive method should be avoided if the algorithm is complex and if there's another way to do it for almost the same computation time... Particulary if other peoples will prolly work in this method.
For your exemple it's ok since it's a short method, but anyway if you'r just not concerned by performances you could have used something like that:
// sorts int values
public static int[] sort(Integer... intValues) {
ArrayList list = new ArrayList(
for ( Integer i : intValues ) {
list.add(i);
}
Collections.sort(list);
return list.toArray();
}
A simple way to implement your method, easily readable by all java >= 1.5 developper, that works for 1 to n integers...
Not the fastest but anyway if it's just about speed use c++ or asm :)
For this particular example, I wouldn't use anything you suggested.. I would instead write:
public boolean endOther(String a, String b){
String alower=a.toLowerCase();
String blower=b.toLowerCase();
if ( a.length() < b.length() ){
return blower.endsWith(alower);
} else {
return alower.endsWith(blower);
}
}
While the ternary operator does have its place, the if statement is often more intelligible, especially when the operands are fairly complex. In addition, if you repeat code in different branches of an if statement, they will only be evaluated in the branch that is taken (in many programming languages, both operands of the ternary operator are evaluated no matter which branch is selected). While, as you have pointed out, this is not a concern in Java, many programmers have used a variety of languages and might not remember this level of detail, and so it is best to use the ternary operator only with simple operands.
One frequently hears of "recursive" vs. "iterative"/"non-recursive" implementations. I have not heard of any particular names for the various options that you have given.
In any case, my recommendation would be to do as little in each statement as possible. The more things that you do in a single statement, the more confusing it will be for others who need to maintain your code.
In terms of your complaint about repetitiion... if there are several lines that are being repated, then it is time to create a "helper" function that does that part. Function composition is there to reduce repitition. Swapping just doesn't make any sense to do, since there is more effort to swap than to simply repeat... also, if code later in the function uses the parameters, the parameters now mean different things than they used to.
EDIT
My argument vis-a-vis the ternary operator was not a valid one... the vast majority of programming languages use lazy evalution with the ternary operator (I was thinking of Verilog at the time of writing, which is a hardware description language (HDL) in which both branches are evaluated in parallel). That said, there are valid reasons to avoid using complicated expressions in ternary operators; for example, with an if...else statement, it is possible to set a breakpoint on one of the conditional branches whereas, with the ternary operator, both branches are part of the same statement, so most debuggers won't split on them.
It is slightly better to use another method instead of recursion
public boolean endOther(String a, String b) {
return a.length() < b.length() ? endOtherImpl(b,a):endOtherImpl(a,b);
}
protected boolean endOtherImpl(String longStr,String shortStr)
{
return longStr.toLowerCase().endsWith(shortStr.toLowerCase());
}
I remember reading a book named:
Java Puzzlers Traps, Pitfalls, and Corner Cases
that described odd behavior in Java code. Stuff that look completely innocent but in actuality perform something completely different than the obvious. One example was:
(EDIT: This post is NOT a discussion on this particular example. This was the first example on the book I mentioned. I am asking for other oddities you might have encountered.)
Can this code be used to identify if a number is odd or not?
public static boolean isOdd(int i) {
return i % 2 == 1;
}
And the answer is of course NO. If you plug a negative number into it you get the wrong answer when the number is odd. The correct answer was:
public static boolean isOdd(int i) {
return i % 2 != 0;
}
Now my question is what are the weirdest, most counter intuitive piece of Java code you came across? (I know it's not really a question, maybe I should post this as a community wiki, please advice on that as well)
One I blogged about recently, given the following two classes:
public class Base
{
Base() {
preProcess();
}
void preProcess() {}
}
public class Derived extends Base
{
public String whenAmISet = "set when declared";
#Override void preProcess()
{
whenAmISet = "set in preProcess()";
}
}
what do you think the value of whenAmISet will be when a new Derived object is created?
Given the following simple main class:
public class Main
{
public static void main(String[] args)
{
Derived d = new Derived();
System.out.println( d.whenAmISet );
}
}
most people said it looks like the output should be "set in preProcess()" because the Base constructor calls that method, but it isn't. The Derived class members are initialized after the call to the preProcess() method in the Base constructor, which overwrites the value set in preProcess().
The Creation of New Class Instances section of the JLS gives a very detailed explanation of the sequence of events that takes place when objects are created.
The most counterintuitive concept I came across is the PECS (Producer Extends, Consumer Super) from Josh Bloch. The concept is excellent, but what do you consider the consumer/producer in a situation - the method itself I would think at first. But no, the parameter collection is the P/C in this concept:
public <T> void consumeTs(Collection<? extends T> producer);
public <T> void produceTs(Collection<? super T> consumer);
Very confusing sometimes.
In fact, Java Puzzlers has 94 more puzzles which exhibit sometimes strange and sometimes deceiving behaviors by mostly innocent-looking code.
We once stumbled upon something like this in a legacy code base (originally camouflaged by a 5 level inheritance structure and several indirections):
public abstract class A {
public A() {
create();
}
protected abstract void create();
}
public class B extends A {
private Object bMember=null;
protected void create() {
bMember=getNewObject();
}
}
When you call B constructor, it calls A default constructor, calling B's create() method, through which bMember gets initialized.
Or so we naively thought. Because after calling super(), the next step in the initialization process is the assignment of explicitly defined default values to B members, in effect resetting bMember to null.
Program was actually working fine anyway, because bMember got assigned again through another route later on.
At some point we removed the apparently useless null default value for bMember, and suddenly program behavior changed.
i recently discovered that Math.abs(i) does not always produce positive numbers.
Math.abs(Integer.MIN_VALUE) yields -2^31
why? because there is one less positive Integer than negative. 2^31 is one more than Integer.MAX_VALUE and thus overflows to -2^31
i guess the situation is similar in most other languages, but i encountered this in java
I tend to agree with you, but I have read (and hopefully someone can supply a link or two to) articles that explain that Java's '%' is consistent with its '/', and that is enough for anyone. From my own experience:
Java's '%' operator is a little different from some other languages' in its handling of negative inputs. I personally prefer "modulo" operators that return non-negatives, e.g.
-5 % 2 == 1
Which would make your example work. I think there is an official name for this operation, but I can't think of it now so I'll stick with "modulo". The difference between the two forms is that that Java variant of 'a % b' performs 'a/b' and rounds towards zero (and subtracts that result from 'a'), while the preferred operation rounds down instead.
Every practical use of applying % to negative 'a' and positive 'b' that I've seen works more easily if the result 'r' is '0 <= r < b' (one example is finding the offset from the left-most edge of a tile, when mapping points onto tiles on a plane that may extend '< 0'). The one exception to this experience was in a university assignment that performed static analysis of integer arithmetic in Java programs. It was during this assignment that the subtleties of Java's '%' came to light, and I went out of my way to replace it with the "fixed" version. This all backfired, because the point was to simulate how Java does arithmetic, not to implement my own preferred kind.
Have a look at the methods defined in java.util.concurrent.SynchronousQueue:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html
Half of the methods always return null / true / false / zero:
Not exactly obvious when you first start working with it, without reading the docs first.
Odd and even numbers are usually thought of as positive numbers, so I think don't think its useful to think of negative numbers as odd or even. The test is often really to see if the lowest bit is set.
These are both fine for negative numbers as well.
if ((i & 1) == 0) // lowest bit not set.
if ((i & 1) == 1) // lowest bit set.
or
if ((i & 1) != 0) // lowest bit set.