Can I Define Exceptions to Eclipse cleanup rules? - java

Most often the cleanup rules (Preferences > Java > Code Style > Clean Up) in Eclipse work perfectly and create nice-looking code.
But sometimes, especially with comments and concatenated string snippets (like inline SQL queries), the cleanup just messes things up, and destroys my formatting.
Is there a way to say to Eclipse "Don't touch this block of text! I have formatted it just the way I like, and you would make it just less readable"?

I assume you do not really mean ‘Clean Up’, but the ‘Format source code’ option hidden within. It is configured in Preferences > Java > Code Style > Formatter. And, indeed, there is an option called ‘On/Off Tags’. Sadly, it’s off by default. You would now write it like so:
// #formatter:off
StringBuilder sql = new StringBuilder()
.append("SELECT whatever \n")
.append("FROM some_table");
// #formatter:on
It may well be possible that the accepted answer was correct at the time of writing, however, this was introduced in Eclipse 3.5, if I’m not mistaken.

I have experienced the same problem, and while I don't have a solution, I can tell you how I work around the problem.
Because of how formatting works, I deliberately avoid lines of code that are excessively long. In general, when I keep lines short, it makes better decisions as to how to format the code. This can even work with SQL statements, for example:
public static final String SELECT_SOMETHING = "SELECT"
+ "OBJECTID, THIS, THAT, THEOTHER, THING"
+ " FROM DBNAME.DBSCHEMA.TABLE_T"
+ " WHERE ID = ?";
This statement formats reasonably, because where possible items were split apart and concatenated together. When I don't do this, I get unpredictable results:
public static final String SELECT_SOMETHING = "SELECT OBJECTID, SOMETHING FROM DBNAME.DBSCHEMA.TABLE_T WHERE ID = ?";
For comments, I place them all on a single line when possible, and allow it to word wrap when it does the formatting.
Also, it is possible to change the style using the code formatter to make things work better for your coding style. You may want everyone on the team to use the same format, just to avoid conflicts. Because it is easier to compare changes with other developers, or prior versions using your source control tool, even if it makes parts of your code less readable, using the formatter has still been to my advantage.
Still, I understand your frustration when the formatter makes bad decisions!

Feeling iffy about replying to my own question, but there's a workaround I currently do (note: I have these cleanup rules as a save-action):
Save (with Ctrl/Cmd-S, don't know if it matters how you save) the code, and let Eclipse mess up your formatting. Then just press Ctrl/Cmd-Z to undo, and immediately re-save. The format reverts back to its original format and seems to be saved as intended.

For SQL statements in code, you can put a single-line comment character at the end of each line. Then the formatter can't reformat it. It's uglier than not having to do it, but it's prettier than if Eclipse formats it.
StringBuffer sql = new StringBuffer() //
.append("SELECT whatever \n") //
.append("FROM some_table");

No. (To the best of my knowledge, and I have had the same problem and have looked many times hard and long...)

(for Javadoc comments only)
If I have a block of text that formatted just the way I like, I enclose them by the <pre></pre> tags.

if you don't want a field to become final (i.i: because you want to change it while debugging), you just assign it to itself on the constructor. This would get an eclipse warning, but your field will stay non-final.

Related

How to abbreviate "number of <items>" in source code?

I'm new to learning Java and I'm bad at English but I try my best to write good, understandable source code.
I want to make variables to save the "number of cars" or "number of items". How do I abbreviate "number of ..." without using symbols like # that don't work in a source code?
Thanks
You have several choices to do that
numberOfItems (verbose, but clear in meaning)
numItems (it's ok)
itemCount (probably, the best — what I'd have used)
items (shortest, but can't know if it is an integer or a list of items)
I try my best to write good, understandable source code
Then my best advice would be not to abbreviate variable names.
Just go with numberOfCars.
Why?
I know you've probably seen a lot of programs where people use one-letter variables or stuff like numCars.
Abbreviating your variables make your code less clear for others (including you in 6 months).
We all have great text editors with auto-completion on variables, use that.

Can Java skip .toUpperCase() on literal string constants already in upper case?

I have a .toUpperCase() happening in a tight loop and have profiled and shown it is impacting application performance. Annoying thing is it's being called on strings already in capital letters. I'm considering just dropping the call to .toUpperCase() but this makes my code less safe for future use.
This level of Java performance optimization is past my experience thus far. Is there any way to do a pre-compilation, set an annotation, etc. to skip the call to toUpperCase on already upper case strings?
What you need to do if you can is call .toUpperCase() on the string once, and store it so that when you go through the loop you won't have to do it each time.
I don't believe there is a pre-compilation situation - you can't know in advance what data the code will be handling. If anyone can correct me on this, it's be pretty awesome.
If you post some example code, I'd be able to help a lot more - it really depends on what kind of access you have to the data before you get to the loop. If your loop is actually doing the data access (e.g., reading from a file) and you don't have control over where those files come from, your hands are a lot more tied than if the data is hardcoded.
Any many cases there's an easy answer, but in some, there's not much you can do.
You can try equalsIgnoreCase, too. It doesn't make a new string.
No you cannot do this using an annotation or pre-compilation because your input is given during the runtime and the annotation and pre-compilation are compile time constructions.
If you would have known the input in advance then you could simply convert it to uppercase before running the application, i.e. before you compile your application.
Note that there are many ways to optimize string handling but without more information we cannot give you any tailor made solution.
You can write a simple function isUpperCase(String) and call it before calling toUpperCase():
if (!isUpperCase(s)) {
s = s.toUpperCase()
}
It might be not significantly faster but at least this way less garbage will be created. If a majority of the strings in your input are already upper case this is very valid optimization.
isUpperCase function will look roughly like this:
boolean isUpperCase(String s) {
for (int i = 0; i < s.length; i++) {
if (Character.isLowerCase(s.charAt(i)) {
return false;
}
}
return true;
}
you need to do an if statement that conditions those letters out of it. the ideas good just have a condition. Then work with ascii codes so convert it using (int) then find the ascii numbers for uppercase which i have no idea what it is, and then continue saying if ascii whatever is true then ignore this section or if its for specific letters in a line then ignore it for charAt(i)
sorry its a rough explanation

stringbuffer and "0&" causes truncation or escaping

Sorry for the unclear title but I don't even know what to call it, I'll just go ahead and explain what's happening.
I'm using a Stringbuffer to build an URL. It looks like this:
http://maps.googleapis.com/maps/api/geocode/json?latlng=49.0516736,8.38891840&sensor=false
I encountered this behavious when comparing this string in a Unit-test to the actual result of the method.
And this is the assertion-error I'm getting:
latlng=49.0516736[,8.38891840]&sensor=false> but was:<...on?latlng=49.0516736[,8.3889184]&sensor=false
The emphasis is on the character sequence 0]& and 4]& right before sensor=false
IF I remove the zero before the & the test goes green.
then the created string looks like this:
latlng=49.0516736,8.3889184&sensor=false
so ... just as expected.
It's not the problem, that the 0 itself gets truncated and test would fail - I've proved that my code is doing what it's supposed to (when I remove the zero), but I want to know what is happening here.
0& must be some kind of indication for array-access or some kind of escaping. I don't know.
Anyone any idea what's causing this behaviour?
Edit:
Here's the code I'm using
StringBuffer s = new StringBuffer( grailsApplication.config.geocodingurl.toString() )
s.append(coordinates.latitude)
s.append(",")
s.append(coordinates.longitude)
s.append("&sensor=false")
return s.toString()
There is a formatting/padding issue when converting double into String.
What you are doing is probably using StringBuilder#append(double) which in the end calls Double#toString().
See the javadoc of those methods and find out how double values are converted to String.
Alternatively, if you want to have control over your code, use NumberFormat or it's subclasses.

Java-Mode Argument Indenting in Emacs

My java-mode in emacs wants to indent function arguments like this:
someLongFunctionName(
argumentNumberOne,
argumentNumberTwo,
argumentNumberThree,
argumentNumberFour
);
There are two problems here. Firstly, it wants to line up the start of the arguments with the end of the function name. Secondly, it wants to treat the the closet paren as if it were an argument, and thus lines it up with all other arguments. I don't like either of those behaviors.
I would much rather it indent my code like this:
someLongFunctionName(
argumentNumberOne,
argumentNumberTwo,
argumentNumberThree,
argumentNumberFour
);
c-mode does a much better job of this by default, and I would like to carry over the behavior to java-mode if possible.
I still need to learn how the emacs indentation engine works, and at the moment I don't honestly really even know that much lisp. Those two learning exercises are definitely on my plate, but at the moment a quick copy-paste solution would be pretty awesome.
Try this
(defun my-indent-setup ()
(c-set-offset 'arglist-intro '+))
(add-hook 'java-mode-hook 'my-indent-setup)
From http://www.emacswiki.org/emacs/IndentingC

Java's String.replace() vs. String.replaceFirst() vs. homebrew

I have a class that is doing a lot of text processing. For each string, which is anywhere from 100->2000 characters long, I am performing 30 different string replacements.
Example:
string modified;
for(int i = 0; i < num_strings; i++){
modified = runReplacements(strs[i]);
//do stuff
}
public runReplacements(String str){
str = str.replace("foo","bar");
str = str.replace("baz","beef");
....
return str;
}
'foo', 'baz', and all other "targets" are only expected to appear once and are string literals (no need for an actual regex).
As you can imagine, I am concerned about performance :)
Given this,
replaceFirst() seems a bad choice because it won't use Pattern.LITERAL and will do extra processing that isn't required.
replace() seems a bad choice because it will traverse the entire string looking for multiple instances to be replaced.
Additionally, since my replacement texts are the same everytime, it seems to make sense for me to write my own code otherwise String.replaceFirst() or String.replace() will be doing a Pattern.compile every single time in the background. Thinking that I should write my own code, this is my thought:
Perform a Pattern.compile() only once for each literal replacement desired (no need to recompile every single time) (i.e. p1 - p30)
Then do the following for each pX: p1.matcher(str).replaceFirst(Matcher.quoteReplacement("desiredReplacement"));
This way I abandon ship on the first replacement (instead of traversing the entire string), and I am using literal vs. regex, and I am not doing a re-compile every single iteration.
So, which is the best for performance?
So, which is the best for performance?
Measure it! ;-)
ETA: Since a two word answer sounds irretrievably snarky, I'll elaborate slightly. "Measure it and tell us..." since there may be some general rule of thumb about the performance of the various approaches you cite (good ones, all) but I'm not aware of it. And as a couple of the comments on this answer have mentioned, even so, the different approaches have a high likelihood of being swamped by the application environment. So, measure it in vivo and focus on this if it's a real issue. (And let us know how it goes...)
First, run and profile your entire application with a simple match/replace. This may show you that:
your application already runs fast enough, or
your application is spending most of its time doing something else, so optimizing the match/replace code is not worthwhile.
Assuming that you've determined that match/replace is a bottleneck, write yourself a little benchmarking application that allows you to test the performance and correctness of your candidate algorithms on representative input data. It's also a good idea to include "edge case" input data that is likely to cause problems; e.g. for the substitutions in your example, input data containing the sequence "bazoo" could be an edge case. On the performance side, make sure that you avoid the traps of Java micro-benchmarking; e.g. JVM warmup effects.
Next implement some simple alternatives and try them out. Is one of them good enough? Done!
In addition to your ideas, you could try concatenating the search terms into a single regex (e.g. "(foo|baz)" ), use Matcher.find(int) to find each occurrence, use a HashMap to lookup the replacement strings and a StringBuilder to build the output String from input string substrings and replacements. (OK, this is not entirely trivial, and it depends on Pattern/Matcher handling alternates efficiently ... which I'm not sure is the case. But that's why you should compare the candidates carefully.)
In the (IMO unlikely) event that a simple alternative doesn't cut it, this wikipedia page has some leads which may help you to implement your own efficient match/replacer.
Isn't if frustrating when you ask a question and get a bunch of advice telling you to do a whole lot of work and figure it out for yourself?!
I say use replaceAll();
(I have no idea if it is, indeed, the most efficient, I just don't want you to feel like you wasted your money on this question and got nothing.)
[edit]
PS. After that, you might want to measure it.
[edit 2]
PPS. (and tell us what you found)

Categories

Resources