Win a copy of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams this week in the Reactive Progamming forum!

Stephan van Hulst

Saloon Keeper
+ Follow
since Sep 20, 2010
Cologne, Germany
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Rancher Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Stephan van Hulst

Operator precedence only comes into play after the compiler has determined what the operands are in the first place.

For instance, in the expression 3 + 2 * 5, operator precedence determines that the multiplication operator binds stronger to the 2 operand than the addition operator does, but only AFTER the compiler has determined that 3, 2 and 5 are valid operands.

new (Main().probe(a)) can't be parsed because the new operator doesn't take an expression as its operand, but a class name and an argument list.
9 hours ago
My last post was in response to the sum of a collection of numbers.

The product of an empty collection of numbers is 1. It's the only thing that makes sense mathematically.
1 day ago
Returning 0 is the only acceptable option to me.

If we didn't have zero to express the lack of things to sum together, we'd be back in the time before Fibonacci introduced Arabic numerals to Europe.
1 day ago
Right, seems like you have no choice. Just try not to get too hung up on the differences between imperative and declarative programming and accept that they both exist and can both be used.

Piet Souris wrote:what is the sound of ZERO  clapping hands?

Zero oscillations of my eardrum.
1 day ago
Well, you can use a different functional interface, such as Function<String, String>, but other than that not really. Java is a statically typed language, and you must specify the types of parameters explicitly, even if the parameter holds a function.

This is not any different in languages like Scala or Haskell, except there the type is specified by typing something similar to String -> String instead of Function<String, String>.

I strongly recommend that if you want to learn more about functional programming, you stop asking questions and start writing programs in a language that doesn't leave you any choice, such as Haskell. You are not doing yourself a favor by constantly comparing a procedural programming style to a functional programming style.

I know you're also learning Scala and C#, and I think you've shot yourself in the foot trying to learn multiple languages before you've mastered one. Finish your education in Java and focus on the old procedural style. If you feel confident, Google LearnYouAHaskellForGreatGood. It's one of the best written tutorials I've ever come across.
Welcome to CodeRanch!

Use one of JOptionPane's show...() methods to create modal dialogs. I recommend using the showConfirmDialog() so you can use OK and Cancel buttons. You can use the message parameter to pass it a panel that contains your user name and password fields. Make sure to check the return value to see if the user cancelled the dialog.
1 day ago

Deepak Amar wrote:I just have a question regarding this "bitwise operators are very natural for working with powers of two". Why do we say that?

Because every bit in a bit sequence represents a power of two.
1 day ago
It depends on the situation. Some problems are easier to solve using procedural programming, usually when the state of the application has to vary with time. That's why functional languages like Haskell have something called "do notation", which really is procedural programming, no matter how much functional programming aficionados insist that it's not.

The ability to see which approach is appropriate comes with experience. You only get that by practicing and have your work peer reviewed.
2 days ago
Well yes, it's personal preference. Take a look at the following application:

Why did I extend Rectangle? You might chalk it up to my eccentric preference to make everything fit in boxes. Similarly, there's never a good technical reason to extend Thread; it only serves to confuse programmers that don't share the same preference.

No application IS a rectangle. No runnable task IS a method of execution of said task.
2 days ago
It's mostly because these examples use the forEach method, and forEach is not functional. forEach is procedural, even if it accepts a function object.

The expressiveness of higher order functions becomes apparent when you use the classical operators, like map, filter, and reduce/collect. Compare the following two code snippets:



As you can see, the difference is code length is not that great. You need to let go of this idea that shorter code is the main advantage of functional programming, or even an advantage at all. The advantage of functional programming is that you tell the computer WHAT you want it to compute and not HOW you want it to compute it.

In the first snippet, we first had to tell the machine to create an ArrayList. We also had to tell it to call the List.add() method to add cities to the list. In the second snippet, we just told it that we are only interested in African countries, we want their capital cities, and we want a list of them. We don't care where the list comes from or how the cities are added to it.

Note also that I haven't used any lambda expressions. I THINK that whenever you say lambdas, you really mean functional operators. Lambda's are just a convenient way to to create a single use function when you don't want to make a separate method to call instead.
2 days ago
Like Campbell, I'm confused by what specifically you are referring to. I first though you were referring to the methods that accept a BiFunction or a BiConsumer.

If you are indeed referring to bitwise operators instead of binary operators, then it's because maps grow in powers of two, and bitwise operators are very natural for working with powers of two.
2 days ago

Because the table uses power-of-two masking

Hash tables grow in powers of two. Imagine you have a map with both capacity and size 4, and you add another element. The table will then double in size to accommodate the new element. An easy way to use the hash of an object to get an index into the table is to just mask the hash with the appropriate power of two, minus one. For example, if you have an object with a hash of which the least significant four bits are 1101, and the capacity of the table is 8, you perform 1101 & (capacity - 1) to get 101 (5 decimal), an index that fits inside the table.

sets of hashes that vary only in bits above the current mask will always collide

Imagine one object generates a hash code that ends in 00011101, and another object generates a hash code that ends in 01011101. If the capacity of the table is 8, both hashes will yield index 5, because only the least significant three bits (101) are used. That means it's very likely that objects will collide if the least significant bits are generated from a field that rarely differs in value between objects.

So we apply a transform that spreads the impact of higher bits downward.

This means that the the most significant 16 bits are xor'ed with the least significant bits of the hash code, to increase the chances of two similar objects having different bit sequences that are used for the table index.

Because many common sets of hashes are already reasonably distributed (so don't benefit from spreading), and because we use trees to handle large sets of collisions in bins, we just XOR some shifted bits in the cheapest possible way to reduce systematic lossage, as well as to incorporate impact of the highest bits that would otherwise never be used in index calculations because of table bounds.

Usually the hash codes that objects generate are already distributed well enough. And even if a collision occurs, the collision is resolved by performing an insert into a binary tree, which is reasonably efficient. That means that an extra transformation that makes sure that hash codes are uniformly distributed would be a useless waste of performance. Xor'ing the least significant bits of a hash code with its most significant bits is just a really cheap optimization that prevents a very specific class of hash codes from resulting in really poor hash table performance.
2 days ago
It happens to the best of us

Welcome to CodeRanch!
4 days ago
Please note that threads really should not be extended. Heck, they shouldn't even be constructed directly.

In professional code, use an ExecutorService and submit Runnable or Callable.
4 days ago