Win a copy of Modern JavaScript for the Impatient this week in the Server-Side JavaScript and NodeJS forum!

Tobias Bachert

Ranch Hand
+ Follow
since Aug 18, 2016
Cows and Likes
Cows
Total received
18
In last 30 days
0
Total given
0
Likes
Total received
41
Received in last 30 days
0
Total given
5
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Tobias Bachert

The string pool does not prevent garbage collection if no strong references to the interned string exist. A literal is eligible for garbage collection if the containing class is eligible for garbage collection (assuming that no other strong references exist). (See also this thread.)

Dave Tolls wrote:There's only one foo.bar.SomeClass (well, outside of multiple class loaders, but then a != b in that case anyway).


That was my point :) - as soon as you have two class loaders with a foo.bar.SomeClass, you have two different classes with the same name, thus checking the name is not sufficient.
Comparing the names won't give the correct answer as two classes with the same name may be loaded; a.getName() == b.getName() does not imply a == b.
Static initializers are executed when the class gets initialized, not when it gets loaded. A class can be initialized by accessing a field (that is not a compile time constant), invoking a method, calling Class#forName, etc..., for a more complete list see JLS 12.4.
3 years ago
I did not post the whole code as it would have forced me to rewrite code (not something I wanted to do at ~4am :D); but the previous code should contain sufficient information to add the missing parts.
The following code requires Java9 and compiles; the same is possible with Java8 (with the corresponding classes of sun.* instead of jdk.internal.* - simply replace #getTagAt with a try-catch block, obtain the unsafe instance via reflection and change the regex to match the verbose:class output).
The JVM loads quite a few classes on startup - as the strings are already in the pool at least one of them has to contain code that contains the literal and has to be executed prior the main method is invoked.

A short scan of the loaded classes for a Java9 version (obtained by using -verbose:class) shows, that two of the loaded classes contain the literals:
java.lang.VersionProps - contains "java", reason for "java" being interned (static field initializer contains the literal, class is initialized in init phase 1)
sun.launcher.LauncherHelper - contains "java" and "main", reason for "main" being interned (method for the main-method validation contains the literal)

The used code to scan the classes for the literals:
The objective is to delete (=clear) a range (=sublist) from a list -> the initial approach should be to use list.subList(fromIndex, toIndex).clear().

We expect O(n) performance (as the basic approach would be to shift elements from toIndex to fromIndex and delete the excessive trailing elements, starting with the last one) - a peek into java.util.AbstractList shows that #clear is implemented aswhereas ArrayList and ArrayList$SubList override #removeRange to use an approach similar to the one described above.
3 years ago
I had an eager get method at first - the disadvantage of this is that it requires at least 12+16+4*N bytes per tuple (N := number of elements in a tuple). The lazy tuple requires only 12+4+4=24 bytes (and should be easier for the JIT to inline). (Memory consumption based on 64bit w/ compressed oops.) The huge disadvantage of the lazy tuple implementation is the extremely bad cache locality -> if the tuple has to be accessed often, one can use source.get(index).toArray() (or new ArrayList<>(...) etc.) to get the same performance as with an eager tuple implementation (besides the possible intermediate garbage tuple). As long as the performance details are explicitly documented I would prefer the lazy version over an eager version.
Note: The implementation above is a very simplified implementation, i.e. #indexOf and #contains can be significantly optimized; bulk operations on a tuple can replace modulo operation and offsets array access with one multiplication and one subtraction; etc...
3 years ago
I would use a wrapper implementation that creates the combinations lazily as storing all combinations might require quite a bit memory. A possible skeletal implementation:
3 years ago
If you don't mind iterating two times over the input string, you could use:

Alternatively to process the string in one iteration:
or, if you want to avoid boxing of the indices:
3 years ago
You have to use the result of the ternary operator (assign it to a variable/return it/invoke a method with it/etc.).
(JLS §15.25: "In fact, by the grammar of expression statements (§14.8), it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear.")

Besides that I would allign the code a bit different:

(You are missing parentheses around fizz * buzz in your last version.)
3 years ago
Small correction: String literals are loaded lazily at first usage, not at the start of the program/loading of the class (behavior is not defined by the JVM specification).
They are eligible for GC if the corresponding Class (and Classloader) is eligible for GC, i.e. the following prints true, false, true:
I would omit the #nullFirst/null-check as Comparable#compareTo specifies to throw a NullPointerException for null arguments.
The alternative compareTo method will fail iff either value is NaN; using the #compare method of the wrapper type avoids possible bugs introduced by forgetting over-/underflow or NaN. In my opinion the comparator based approach should be compared to

I agree that the comparator approach may be better readable iff there is more than one value to compare as each value has to be specified only once instead of twice (but would still use Wrapper#compare/manually written comparison if performance is relevant).
vs.
3 years ago
The a==2 should be a==(Integer) 2 (or a==Integer.valueOf(2)), otherwise the examples won't show the desired behavior.