Formatting a table in Java 1.4 - java

I'm required (by my teacher) to use Java 1.4 and I need to use a Formatter to format my output into a table. Is there any other way I can do this?
Right now, I have it looking like this:
System.out.printf("%-15s %-15s %-15s %n", "Name", "Day", "Time");
for (int i = 0; i < show.size(); i++){
System.out.printf("%-15s %-15s %-4d %n", ((showInfo)show.get(i)).name, ((showInfo)show.get(i)).day, ((showInfo)show.get(i)).time);
And it works on the IDE, but when I run it in my command prompt (1.4) it gives me errors. Is there any other way to make the table?
Any help would be great! Thanks in advance!

Java 1.4 doesn't have PrintStream.printf(), it was added in Java 1.5.
You need to make sure that you actually use Java 1.4 in your IDE to be sure that you only use methods that exist in that Java version.
It has been a while since I used Java 1.4, but you have to do the formatting yourself, eg by left padding the string if it is too short.
BTW: Tell your teacher to get with the times, Java 1.4 was released in 2002, Java 5 (1.5) in 2004, Java 6 (1.6) in 2006 and Java 7 (1.7) in 2011. What use is it to constrain students by using outdated and insecure(!) versions of Java?

Related

Idiomatic way to remove country code from currency format?

Somewhere between Java 11 and 17 currency formatting changed to where this:
NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH).format(100.00)
would print 100,00 $ CA instead of 100,00 $.
Is there a better way than this to remove the country code CA?
var currencyFormat = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);
if (currencyFormat instanceof DecimalFormat decimalFormat) {
var symbols = DecimalFormatSymbols.getInstance(Locale.CANADA_FRENCH);
symbols.setCurrencySymbol("$");
decimalFormat.setDecimalFormatSymbols(symbols);
}
Seems a bit much just to get back something that was the default behavior up until recently.
I dug a bit into this, the JDK locale data comes from Unicode CLDR by default, and it seems they reverted from $ CA to $ back in August, see CLDR-14862 and this commit (expand common/main/fr_CA.xml and then go to lines 5914/5923).
This was part of v40, released in October, so too late for JDK 17 whose doc says it uses CLDR v35.1
(which was introduced in Java 13)
but it seems it was updated to v39 in April 2021 and
they forgot the release note
(JDK 16 appears to have been upgraded to v38 already).
CLDR v40 is planned for JDK 19.
You may want to run your application using the COMPAT locales first, with
-Djava.locale.providers=COMPAT,CLDR,SPI
(found here but see also LocaleServiceProvider)
This will use the locales compatible with Java 8, where this issue is not present.

Check if a Java version is greater than a certain iteration in Java?

I wish to check if a user's Java version is at least 1.8.0_171. I mean that specific iteration or higher, meaning 1.8.0_151, for instance, would not work.
I planned to originally use org.apache.commons.lang3.SystemUtils' isJavaVersionAtLeast(JavaVersion requiredVersion) method, but it seems that you cannot specify the iteration number.
Based on this and Java's changing way of representing version numbers in Java (e.g. 1.8 then 9), what is the best way to check the Java version of the user in the Java program?
Edit:
This was marked as a duplicate of this question; however, I think it is different in that it asks how to compare the java version with a certain version given the changes in format of how the java version is shown.
Even with the versioning change, I think the solution is still as simple as using the following boolean expression:
"1.8.0_171".compareTo(System.getProperty("java.version")) <= 0
If the user's java.version property is any less than 1.8.0_171, then the above expression returns false, and vice versa. This works for using "9" or "10" in place of the java.version property as well.

Which "default Locale" is which?

With UNIX locales, the breakdown of which means what is relatively well documented.
LC_COLLATE (string collation)
LC_CTYPE (character conversion)
LC_MESSAGES (messages shown in UI)
LC_MONETARY (formatting of monetary values)
LC_NUMERIC (formatting of non-monetary numeric values)
LC_TIME (formatting of date and time values)
LANG (fallback if any of the above are not set)
Java has a different categorisation which doesn't quite match the real world (as usual):
Locale.getDefault()
Locale.getDefault(Locale.Category.DISPLAY)
Locale.getDefault(Locale.Category.FORMAT)
If you read the documentation on these, Locale.getDefault(Locale.Category.DISPLAY) appears to correspond to LC_MESSAGES while Locale.getDefault(Locale.Category.FORMAT) appears to correspond to some combination of LC_MONETARY+LC_NUMERIC+LC_TIME.
There are problems, though.
If you read the JDK source, you start to find many worrying things. For instance, ResourceBundle.getBundle(String) - which is entirely about string messages - uses Locale.getDefault(), not Locale.getDefault(Locale.Category.DISPLAY).
So I guess what I want to know is:
Which of these methods is supposed to be used for which purpose?
Related, but I made a little test program to see which Java locales corresponded to which UNIX locales and got even more surprising results.
import java.util.Locale;
public class Test {
public static void main(String[] args) {
System.out.println(" Unqualified: " + Locale.getDefault());
System.out.println(" Display: " + Locale.getDefault(Locale.Category.DISPLAY));
System.out.println(" Format: " + Locale.getDefault(Locale.Category.FORMAT));
}
}
Locales according to my shell:
$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
Output of the program:
$ java Test
Unqualified: en_AU
Display: en_AU
Format: en_AU
So it turns out Java doesn't even get it from the UNIX locale. It must be using some other back door to get the settings without using those.
It's hard to understand what you are asking here. Instead, you make a statement that reveals that you're not necessary a Java programmer. It's OK, it does not matter really.
Few things to clarify:
The Locale class is in JDK since Java 1.1
Things like Locale.Builder, Locale.Category and many others are here from Java 7 (JDK 1.7)
Locale-aware classes and methods like DateFormat, NumberFormat, Collator, ResourceBundle, String.toLowerCase(Locale), String.toUpperCase(Locale) and many, many more are here for quite a long time each (long before JDK 1.7)
Prior to Java 7/JDK 1.7 there was only one method of acquiring current OS Locale - call Locale.getDefault() (that is without parameters)
In other words, prior to Java 7, Java's Locale Model was as simple as one system property composed of a language, a country and an optional locale variant. That has changed with Java 7 (end was further extended with Java 8...) and now you have two system properties, one for formatting and one for displaying user interface messages.
The problem is, there is substantial amount of legacy code written in Java and this could shouldn't break when you upgrade the platform. And that is exactly why you still have parameterless Locale.getDefault() around. Moreover (you may test it yourself), Locale.getDefault() is basically interchangeable with Locale.getDefault(Locale.Category.DISPLAY).
Now, I said formatting and user interface messages. Basically, formatting is not only formatting, but things like character case conversion (LC_CTYPE), collation (LC_COLLATE) as well. Sort of anything but user interface messages. Sort of, because default character encoding (which depends on an OS, BTW) is not part of Locale. Instead you need to call Charset.defaultCharset().
And the fallback rules (built in Java, not read from OS) could be worked out with ResourceBundle.Control class. And as we know, it is rather related to UI category...
The reason why Java Locale Model is different from POSIX (not UNIX, it's more universal), is the simple fact that there are quite a few platforms out there. And these platforms doesn't necessary use POSIX... I mean not only Operating Systems, but things like web... Java is striving to be universal and versatile. As the result Java's Locale Model is convoluted, tough luck.
I have to add that nowadays, it's not only the language and the country, but there are also things like preferred script, calendar system, numbering system, specific collation settings and possibly more. It even works sometimes.

Rounding Half Up with Decimal Format in Android

I want to set the Rounding Mode to HALF_UP on my DecimalFormat, but eclipse is telling me that setRoundingMode() is not available on the DecimalFormat class. My project properties (and the overall Eclipse properties) are using the 1.6 compiler. The developer.android.com site says that I can use either Java 5 or 6 so I'm not sure what the problem is.
import java.math.RoundingMode;
import java.text.DecimalFormat;
completedValueFormatter = NumberFormat.getNumberInstance();
DecimalFormat completedDecimalFormat = (DecimalFormat)completedValueFormatter;
completedDecimalFormat.setRoundingMode(RoundingMode.HALF_UP);
I've also tried using the android tools to generate an ant-based project, tried this code in the project and also got the same compile error. So it doesn't appear to be related to Eclipse. It seems related to the Android API.
Any suggestions?
This doesn't truly answer why I can't use the Java 6 .setRoundingMode(RoundingMode) method in DecimalFormat, but it is at least a work-around.
int numDigitsToShow = this.completedValueFormatter.getMaximumFractionDigits();
BigDecimal bigDecimal = new BigDecimal(valueToBeRounded);
BigDecimal roundedBigDecimal = bigDecimal.setScale(numDigitsToShow, RoundingMode.HALF_UP);
return this.completedValueFormatter.format(roundedBigDecimal.doubleValue());
I create a BigDecimal with the value I need to round, then I get a BigDecimal of that value with the scale set to the number of digits I need to round my values to. Then I pass that rounded value off to my original NumberFormat for conversion to String.
If anyone has a better solution, I'm all ears!
Here is what I suspect the problem is, (assuming I am reading the docs properly) and its a doozy:
According to the java.text.DecimalFormat API documentation, you are not actually getting the Runtime Implimentation of the Java 1.6 RE, but are getting an android "Enhanced Version" that clearly doesn't include the setRoundingMode, which frankly bites.
"This is an enhanced version of DecimalFormat that is based on the standard version in the RI. New or changed functionality is labeled NEW."
A weakness in Java for many many many years has been the DecimalFormat class defaulted to HALF_ROUND_UP and had no way to change that, until JVM 1.6. Pity to see Android is keeping this need to kludge alive.
So looks like we are stuck Kludging BigDecimal scale Settings to format output all over any app that needs it, instead of simply being able to rely on a formatter call alone to get the job done. Not the end of the world, but very disappointing Google.
Of course that same doc says that setRondingMode() works, so perhaps this is a all out BUG??
I guess this would be the best option
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html#ceil(double)

Closures in Java 7 [duplicate]

This question already has answers here:
Closure in Java 7 [closed]
(7 answers)
Closed 6 years ago.
I have heard that closures could be introduced in the next Java standard that is scheduled to be released somewhere around next summer.
What would this syntax look like?
I read somewhere that introducing closures in java is a bigger change than generic was in java 5. Is this true? pros and cons?
(By now we definitely know that closures not will be included in the next Java release)
OR
edit: http://puredanger.com/tech/2009/11/18/closures-after-all/ :D
edit2: Re-thinking JDK7: http://blogs.oracle.com/mr/entry/rethinking_jdk7
edit3: There’s not a moment to lose!: http://blogs.oracle.com/mr/entry/quartet
Have a look at http://www.javac.info/ .
It seems like this is how it would look:
boolean even = { int x => x % 2 == 0 }.invoke(15);
where the { int x => x % 2 == 0 } bit is the closure.
It really depends on what gets introduced, and indeed whether it will be introduced at all. There are a number of closure proposals of varying sizes.
See Alex Miller's Java 7 page for the proposals and various blog posts.
Personally I'd love to see closures - they're beautiful and incredibly helpful - but I fear that some of the proposals are pretty hairy.
In November 2009 there was a surprising u-turn on this issue, and closures will now be added to Java 7.
Update
Closures (AKA lambdas expressions) in Java 7 didn't happen. They were finally added in the first release of Java 8 in 2014.
Unofortunately you will not find closure in Java 7. If you are looking for a lighter solution to have closure in java just now check out the lambdaj project:
http://code.google.com/p/lambdaj/
This is the java 7 features http://tech.puredanger.com/java7/#switch the examples are very usefull.
Note that a "function-type" is really a type under the proposal:
{int => boolean} evaluateInt; //declare variable of "function" type
evaluateInt = {int x => x % 2 }; //assignment
I think there is still a lot of debate going in with regards to what syntax will ultimately be used. I'd actually be pretty surprised if this does make it into Java 7 due to all of that.
closures will be annoyinglly verbose if there won't be any sort of type inference... :(
Closures have some serious edge cases. I would say that Closures are a much more significant change than Generics and the later still has a number hairy edge cases.
e.g. The Java Collections libraries cannot be written/compiled without warnings.

Categories

Resources