Hi! Welcome to the blog of this week. For my last blog post, I wrote about Java and why is it popular, I even explained why you should learn Java if you want to enter the universe of programming or if you want to become a Software Engineer/developer. Technology is changing fast, and learning gets very exciting and useful when you need to create something new to then apply it to the development of real-world solutions.
There are several programming languages, and there are also several lists of the most popular programming languages, Java has remained strong, and it seems that you just can go wrong with Java. Nevertheless, as I said technology changes fast, so we need to stay practicing and creating this incredible habit of learning so we can learn something new effectively and fast when necessary.
That’s why to continue my blog post of last week, this week I decided to talk about what I have been learning to get into the Java world fast and effectively. If you already know a programming language, and CS concepts it will take you less time, if not you might need more time, the key is to be patient and constant.
As I wrote in my last post, Java is a programming language designed to be concurrent, class-based, and object-oriented, as well as a computing platform. Java is high-level and designed to have as few implementation dependencies as possible (If you want to go deeper into something, please refer to my last blog post and feel free to do your own research into the subjects you are more interested in).
Once we understand what Java is, and in general terms how does it work, it is now time to practice and learn the language.
Keywords are reserved words that like Java, most of the other programming languages have. Each keyword has a specific use and meaning, and they might also need to be arranged in a specific order. We create Java programs by using these specific keywords, in addition to other tools.
For example, the words public (access modifier), or class (for declaring a class for later use) are keywords. One important thing is that we cannot use these reserved keywords as identifiers in our programs, so be aware of that.
An additional point, talking about naming programs, classes, and variables, there are conventions to follow to make code more readable, like in other languages. As you progress over the language, make sure that you are following these conventions. For variables and methods, we use the lowerCamelCase, for classes we use the UpperCamelCase. For constants we use ALL_CAPITAL_LETTERS, and packages use reversed domain names.
For understanding the different types of variables that exist in java, it would be necessary to understand the basics of OOP first.
In Java we have 4 types of variables:
- Instance Variables (Non-Static Fields): Non-static fields are fields without the static keyword. Non-static fields are known as instance variables since their values are unique to each instance of a class. Declared in a class, but outside a method.
- Class Variables (Static Fields): Fields that use the static keyword to tell the compiler there is exactly one copy of this variable regardless of the number of times that the class has been instantiated. You can also use the final word to tell the value won’t change. Declared in a class, but outside a method.
- Local Variables: Used for storing the temporary state of methods, they are declared just as they are, without any additional keywords, just their primitive data type, and its name. They will be placed inside a code block and will be local to that code block.
- Parameters: Placeholders for values that will be used inside methods.
The Java programming language is statically typed. That is, variables need to be declared before being used, including data type and name.
The 8 primitive data types of Java are:
- byte: signed integer 8-bit, from -128 to 127. Can be used for saving memory in large arrays.
- short: signed integer 16-bit, from -32,768 to 732,767. Can be used for saving memory in large arrays.
- int: signed integer 32-bit, from -2³¹ to 2³¹-1.
- long: signed integer 64-bits, from -2⁶³ to 2⁶³-1;
- float: single-precision 32-bit floating-point number, should never be used for precise values. For that, you will need to use java.math.BigDecimal class instead.
- double: double-precision 64-bit floating-point number, for decimal values, this data type is generally the default choice. Should never be used for precise values.
- boolean: Two possible values, true or false. Used for conditions.
- char: The char data type is a single 16-bit Unicode character. It has a minimum value of ‘\u0000’(or 0) and a maximum value of ‘\uffff’ (or 65,535 inclusive).
- In addition to the eight primitive data types listed above, the Java programming language also provides special support for character strings via the java.lang.String class.
Primitive data types are not objects created from a class.
Operators are special symbols that let us perform operations to operands, an return then a result. It is important to know the precedence of the different operators so we can perform our operations correctly. The Java programming language also provides operators that perform bitwise and bit shift operations on integral types, not only arithmetical operations.
In general, in Java we have:
- Simple assignment operator.
- Arithmetic operators.
- Unary operators.
- Equality and relational operators.
- Conditional operators.
- Type comparison operator.
- Bitwise and bit shift operators.
Here you can find more extended information.
Expressions, Statements, and Blocks
An expression consists of variables, operators, and method invocations, that evaluate to get a single value.
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution. Types of expression can be assignment expressions, method invocations, and object creation expressions.
There are declaration and control flow statements. Declaration statements declare a variable while control flow statements regulate the order in which statements get executed.
A block is a group of zero or more statements between balanced braces and can be used anywhere a single statement is allowed.
Control Flow statements
These statements break up the flow of execution of your program by employing decision-making, looping, and branching, so we can execute particular blocks of code conditionally.
Java supports the following control statements:
- Decision-making statements: if-then, if-then-else, switch.
- Looping statements: for, while do-while.
- Branching statements: break, continue, return.
The if-then statement can be seen as the most basic control flow statement. If a particular condition evaluates to true, then it enters to a specific code block.
On the other hand, if-then-else gives you the option to create another path when the condition for the if statement evaluates to false.
In addition, we can create paths like if-else if-else if…-else with the purpose of creating more than two paths and evaluate for different values of something.
The switch statement works almost the same, it allows you to check different values for a variable and do something depending on its value.
The while and do-while continually execute a block while a particular condition is true, the main difference between the two is that the do-while checks its condition at the bottom, hence, the block will always execute at least once.
The for statement is a tool to iterate over a range of values in a compact form. In Java, there are two forms of this loop, one of them designed for looping specifically through collections and arrays.
Here I will share with you some of the exercises that I worked on in order to practice what I have learned so far. My solutions implement all of the things that we have been talking about. Notice that the purpose of this exercise is to create arithmetic solutions, without using strings, for example.
- Check if a number is a palindrome. That is, check if a number can be reversed and still being the same number.
This solution does the following:
- Change the number to positive, otherwise, you will get a wrong answer with this solution.
- We take the original number and go through each digit, how? Here I use the modulus operator to extract the last digit on the number in each iteration, while I divide the number by ten each cycle to move through the digits. We multiply the current value by ten to maintain the last digit we added and move it to the next position.
- If number = 121, we do newnumber = (0 * 10) + (121 % 10) = 1. Then we do newnumber = (1 * 10) + (12 % 10) = 12 and so on. We then return a boolean to tell if it is a palindrome or not.
2. Determine if a number is perfect or not. A perfect number is a positive integer that is equal to the sum of its proper divisors. Proper divisors are positive integers that divide the perfect number giving a 0 remainder, excluding the perfect number itself.
- First, the number must be greater than one.
- Second, we go through numbers from 1 to the number we are checking, without including it. If the number is fully divided by one of our current values, we add that number to a sum variable.
- Finally, we check if our sum is equal to the number so it is a perfect number or not.
3. Convert a number into words. For example, if we receive 1234, we should print “One”, “Two”, “Three”, and “Four”.
- The first thing to notice is that we can divide by digits and then use a switch statement, for example, to print the number but in words. The problem is that if we get digit by digit using the remainder we would print the number in reverse, since we print the last value first, instead of the first.
- To fix that, we first reverse the number first, our first method reverse also negative numbers. Nevertheless, our numberToWords principal method does not accept negative numbers.
- Then we have another problem, if we reverse 1000, we would get 0001, which is 1. However, we want to print the whole number, that is “One”, “Zero”, “Zero”, “Zero”. To do this we count the digits from our original number and subtract to that number the number of digits of our number after being reversed. That is, 1000 has 4 digits, 1 has 1 digit, the difference is 3, so we need to add 3 times “Zero”.
- All of this was achieved by creating 3 methods, see below the solution.
- You can test the code using:
I have found solving problems very useful to understand better some of the basics of Java, I am going to keep going through the language for solving problems using data structures and other algorithms.
Is it very important to also practice OOP in Java to fully understand the language. Wait for my next blog to see what I have learned about that very important topic.
See you in my next post!