Strings
C# has string
, Java has String
.
Strings are handled similar in both languages. In both cases, strings are class types and are immutable: String methods which seem at first to change the underlying object do not change this object, but create a new one and return the new one.
Escaping in string literals is the similar as in C#. Java knows
"\t, \n"
and the like."\u20ac"
for unicode characters.- Java understands
"\065"
as the octal value 065. This is not available in C#. - Java has no equivalent to the
@
prefix for string constants. But it understands slashes as path separators, also on Windows. - Java does not understand
"\x123"
where 123 is interpreted as hex value.
Both languages have got also mutable string-like classes. C# has StringBuilder
(not thread-safe). Java has StringBuilder
(not thread-safe) and StringBuffer
(thread-safe).
Like in C#, indexOf
returns -1 if the searched string is not found.
string s = "abc";
int n = s.IndexOf("c", 7); // n = -1, no exception
Gotcha: In Java, string comparison with ==
does not compare the contents. In C# it does. In Java, you have to use the function equals(..)
to compare the contents of strings.
String Formatting
Java supports the old and well known C string formatters. C# doesn’t.
System.out.printf("Creating date: %02d.%02d.%04d", 10, 4, 2014);
// 10.04.2014
String s = String.format(">%6.2f<", 3.14159265359);
// s is > 3,14< in Germany.
// Yes, like in C#, the locale is used for formatting.
s = String.format(Locale.ENGLISH, ">%6.2f<", 3.141592);
// s is > 3.14<.
String Parsing
// Java
int i = Integer.parseInt("22");
int j = Integer.parseInt("ab"); // NumberFormatException
Java does not have TryParse
functions.
Console
Output to Stdout
Output to stdout is done via System.out.print*
.
System.out.println(); // only newline
System.out.println("abc"); // abc + newline
System.out.print("abc"); // abc without newline
System.out.print("abc\n"); // abc + newline
System.out.print("a" + "bc" + "\n"); // abc + newline
Java does not support C#-like formatted printing with {0}
and {1}
and so on. Instead, it supports formatted printing with a C-like printf
function with some extensions. I'm giving some examples here but won't go into details.
System.out.printf("'%d'", 3); // '3'
System.out.printf("'%3x'", 10); // ' a'
System.out.printf("'%03d'", 3); // '003'
String[][] z = {
{ "Name", "Anna" },
{ "Age", "27" },
{ "Sex", "Female" },
};
for (String[] s : z)
System.out.printf("%-5s:%7s", s[0], s[1]);
// This prints:
Name : Anna
Age : 19
Sex : Female
Find a tutorial of Java's string formatting possibilities with printf
and format
there: http://docs.oracle.com/javase/tutorial/essential/io/formatting.html. And find the full format string syntax here:
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax.
Input From Stdin
System.out.print("\nEnter your weight:");
double weight = sc.nextDouble();
sc.nextLine(); // needed to consume the enter-key
// left by the input of the double
System.out.print("\nEnter your name:");
String name = sc.nextLine();
System.out.print("\nEnter your size in cm:");
int size = sc.nextInt();
System.out.printf("\nWeight: %g Name: %s Size: %d",
weight, name, size);
Gotcha: After
Scanner sc = new Scanner(System.in);
sc.close();
sc = new Scanner(System.in);
sc.nextInt();
you'll get an NoSuchElementException
in the last line. It is because sc.close()
closes not only the Scanner, but also the System.in
stream. Which cannot be reopened. So if you want to have a Scanner
in your program which is bound to System.in
, you can not close it if you may need it any time later in the same program.
Enums
There are enums in both languages, but there are huge differences. In C#, enums are implemented very similar to C and C++, as some special integers. They are derived from type Enum
which is derived from one of the integer value types.
In Java, enumerations are also derived from a type called Enum
, but this is a class, a reference type. There are no traces of underlying integers like in C#.
Like classes, enums can be defined in an own source file, as a subtype of another class or as a non-public type in a source file with another public type.
public enum Fruit { BANANA, ORANGE, APPLE, LEMON, PEAR };
or
public class A
{
enum SortOrder { ASCENDING, DESCENDING };
}
or
public class A
{
...
}
enum Erinyes { Alecto, Megaera, Tisiphone };
The main methods of Enum
are shown here.
Fruit a = Fruit.BANANA;
System.out.println(a.name());
// -> BANANA name() is not overridable
System.out.println(a.toString());
// -> BANANA toString() is overridable
Fruit b = Fruit.valueOf("APPLE"); // Create an enum from its name
System.out.println(b.name()); // APPLE
// Create an enum from its name, 2nd possibility:
Fruit c = Enum.valueOf(Fruit.class, "ORANGE");
// The ordinal() value is used to sort enums.
// You cannot change the ordinal value
// aside of by changing the order in the definition.
System.out.printf("%s:%d\n", c, c.ordinal()); // ORANGE:1
System.out.println(a.compareTo(b)); // -2
for(Fruit i: Fruit.values())
System.out.printf("%s:%d ", i.name(), i.ordinal());
// -> BANANA:0 ORANGE:1 APPLE:2 LEMON:3 PEAR:4
// In contrast to Java's behaviour for strings,
// the == operator for enums does what you expect.
Fruit d = Fruit.ORANGE, e = Fruit.ORANGE;
if(d == e)
System.out.println("=="); // ==
if(d.equals(e))
System.out.println("equal"); // equal
Fruit k = Fruit.valueOf("Grapple"); // IllegalArgumentException
Flags
In C#, you can define and use a set of flags like this:
[Flags]
enum Spices { None, Salt=1, Pepper=2, Chili=4, Paprika=8 };
void Main()
{
Spices x = Spices.Salt | Spices.Pepper;
Console.WriteLine(x); // Salt, Pepper
}
This is not possible in Java. In Java, you have to use a set of enums to represent flags. The type EnumSet
is designed for that.
enum Spices { SALT, PEPPER, CHILI };
EnumSet s = EnumSet.noneOf(Spices.class); // s is empty.
s = EnumSet.allOf(Spices.class); // s is (SALT | PEPPER | CHILI)
s = EnumSet.of(Spices.PAPRIKA, Spices.CHILI); // s is (PEPPER | CHILI)
s = EnumSet.complementOf(s); // s is (SALT)
EnumSet z = EnumSet.copyOf(s); // z is (SALT)
System.out.println(z); // [SALT]
Enum With Methods, Properties And Constructors
You can add methods and properties to an enum like to any ordinary class. You can override virtual methods and you can add constructors. You cannot create an enum that is derived from another enum.
public enum Flavors { SWEET, SOUR, SPICY };
public enum Fruit
{
BANANA(EnumSet.of(Flavors.SWEET)),
ORANGE(EnumSet.of(Flavors.SWEET, Flavors.SOUR)),
LEMON(EnumSet.of(Flavors.SOUR));
private Fruit(EnumSet flavors)
{
this.flavors = flavors;
}
@Override
public String toString()
{
return name().toLowerCase() + flavors.toString();
}
public String toGerman()
{
switch(name())
{
case "BANANA":
return "Banane";
case "ORANGE":
return "Orange";
case "LEMON":
return "Zitrone";
}
return null;
}
private EnumSet flavors;
};
System.out.println(Fruit.BANANA.toString()); // banana[SWEET]
System.out.println(Fruit.ORANGE); // orange[SWEET, SOUR]
System.out.println(Fruit.LEMON.toGerman()); // Zitrone