To me this thread shows exactly what is wrong with our profession. Too
many people read the marketing literature and take it as gospel.
You
use EJB when and only when you need the container services. That is,
transaction, persistence and security. Now if you follow the advice of
most and don't use Entity beans that leaves you with security and
transaction. Very few people use the security features on EJB so that
leaves you with transactions. There are many other often easier ways to
deal with transactions though so it is still questionable if you ever
need EJB.
Let us examine some of the comments made so far.
1.
Scalability - Why is it more scalable? If you are using Stateless
session beans you are scalable because you are stateless. But if you are
stateless it is just as easy to use POJOs (Plain old Java Objects) .
Stateless design leads to better scalability but EJBs are not necessary
to make your application stateless. Again the only advantage is the
container services provides - otherwise it is just code folks - and your
code will work just fine.
While we are at it lets address
another common misconception. Lifecycle management. It is often claimed
that EJB gives you some necessary lifecycle management and object
pooling. It also is supposed to help you in a multi threaded
environment. The trouble with this claim is that if you are stateless
there are no threading issues and you only need one instance to handle
all of your clients on a server. Servlets and stateless Session beans
are essentially equivalent ( keep in mind that HTTPServlets are only one
type of Servlet). In the world of Servlets the spec allowed you to
either create a new Servlet for every client or to use one and make it
thread safe. Every servlet container does it the second way and yet EJB
only allows containers to do it the first way.
2. Performance -
??? What are they doing to improve performance. I can either call an
object directly or go through layers of infrastructure - which do you
think would be faster. Again only if we need the infrastructure is it an
advantage (and NONE of the EJB infrastructure is to help with
performance).
3. Maintainability - If I use OO programming
methodology instead of the procedural based EJB I will be better off not
worse off here. Why do people think that only EJB will get you
modularity? Also testability is more difficult with EJB then POJOs and
by decreasing testability I decress maintainability.
4.
Different clients - Granted you need a server to handle the different
clients but you don't need EJB for them to all call the same code. You
just need the same object to call. Objects themselves don't care about
who your client is. If I have some object Foo with method bar and that
method is such that I can have copies of it in different app servers
that are all the same ( a requirement for clustering) then all I have to
do is have each client create a Foo and call foo.bar(). Why is it
better to do the JNDI lookup to find the Foo (when they are all the
same) and then use an RMI layer to call the bar. Even if we are calling
the database here it is the conection pooling and the database that
gives you your advantages - and there were connection pools long before
there were app servers and you can use them in an AppServer even if you
are a POJO.
5. Database access - One poster said if you use your
JSP/Servlets to access the database all the time it will be slower
because you don't get help from the container. This is a false
dichotomy. I can still have an object layer and a data access layer and
never have my JSP/Servlets directly make SQL calls. I don't need EJB for
that and unless you are using Entity beans which means you have an
extremely simple domain model, the container is doing nothing for you
here.
History is important here. EJB arose out of a desire to
make CORBA easier to deal with. The reason you would use CORBA is as an
integration technology. You had a system (maybe an old batch system)
that you wanted to access from an OO or other program. With a CORBA
interface you could make it more object like to the client. When doing
this properly there were some cross cutting concerns that crop up like
Transaction management, Security etc that people designed frameworks to
get around. EJB was supposed to help here. The problem is that the
context - a wrapper for older technology or across system boundaries was
lost and now people advocate using EJB when it is all one system, you
don't distribute, and it is a brand new app. But why? I love JMS for
integration but I don't think you should endlessly send messages to
yourself within an application.
Most projects should have at
most one or two EJBs but I see people create systems with hundreds of
them. This is stupid and wasteful. You have made your build times
longer, your deployments more complex, and your code harder to test.
What would be better for our industry is for people to actually learn
about OO Design and stop with trying to shove procedural technology in
the way and calling that progress.
source: http://www.theserverside.com/discussions/thread.tss?thread_id=30165
Showing posts with label PROGRAMMING. Show all posts
Showing posts with label PROGRAMMING. Show all posts
Thursday, 17 July 2014
Friday, 21 February 2014
[HIBERNATE] property: hibernate.hbm2ddl.auto
hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.e.g. validate | update | create | create-drop
So the list of possible options are,
- validate: validate the schema, makes no changes to the database.
- update: update the schema.
- create: creates the schema, destroying previous data.
- create-drop: drop the schema at the end of the session.
These options seem intended to be developers tools and not to facilitate any production level databases, you may want to have a look at the following question; Hibernate: hbm2ddl.auto=update in production?
Wednesday, 19 February 2014
[HIBERNATE] one-to-one mapping using annotations
Hibernate one-to-one mapping using annotations
If you are working on any hibernate project or you are planning to work on any in future, then you can easily understand the one-to-one relationships between several entities in your application. In this post, i will discuss variations of one-to-one mappings supported in hibernate.
Download source code
Lets see them in action one by one:
Table structure will be like this:

To make such association, refer the account entity in EmployeeEntity class as follow:
The join column is declared with the @JoinColumn annotation which looks like the @Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join.
If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.
In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.
Above “mappedBy” attribute declares that it is dependent on owner entity for mapping.
Lets test above mappings in running code:
Running above code creates desired schema in database and run these SQL queries.Download source code
Sections in this post: Various supported techniques Using foreign key association Using a common join table Using shared primary keyFor this article, I am extending the example written for hello world example. We have two entities here: Employee and Account.
Various supported techniques
In hibernate there are 3 ways to create one-to-one relationships between two entities. Either way you have to use @OneToOne annotation. First technique is most widely used and uses a foreign key column in one to table. Second technique uses a rather known solution of having a third table to store mapping between first two tables. Third technique is something new which uses a common primary key value in both the tables.Lets see them in action one by one:
Using foreign key association
In this association, a foreign key column is created in owner entity. For example, if we make EmployeeEntity owner, then a extra column “ACCOUNT_ID” will be created in Employee table. This column will store the foreign key for Account table.Table structure will be like this:
To make such association, refer the account entity in EmployeeEntity class as follow:
1.@OneToOne2.@JoinColumn(name="ACCOUNT_ID")3.private AccountEntity account;If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.
In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.
1.@OneToOne(mappedBy="account")2.private EmployeeEntity employee;Lets test above mappings in running code:
01.public class TestForeignKeyAssociation {
03. public static void main(String[] args) {
04. Session session = HibernateUtil.getSessionFactory().openSession();
05. session.beginTransaction();
06.
07. AccountEntity account = new AccountEntity();
08. account.setAccountNumber("123-345-65454");
09.
10. // Add new Employee object
11. EmployeeEntity emp = new EmployeeEntity();
12. emp.setEmail("demo-user@mail.com");
13. emp.setFirstName("demo");
14. emp.setLastName("user");
15.
16. // Save Account
17. session.saveOrUpdate(account);
18. // Save Employee
19. emp.setAccount(account);
20. session.saveOrUpdate(emp);
21.
22. session.getTransaction().commit();
23. HibernateUtil.shutdown();
24. }
25.}
1.Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)2.Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)Using a common join table
This approach is not new to all of us. Lets start with targeted DB structure in this technique.In this technique, main annotation to be used is @JoinTable. This annotation is used to define the new table name (mandatory) and foreign keys from both of the tables. Lets see how it is used:
1.@OneToOne(cascade = CascadeType.ALL)2.@JoinTable(name="EMPLOYEE_ACCCOUNT", joinColumns = @JoinColumn(name="EMPLOYEE_ID"),3.inverseJoinColumns = @JoinColumn(name="ACCOUNT_ID"))4.private AccountEntity account;Testing above entities generates following SQL queries in log files:
1.Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)2.Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)3.Hibernate: insert into EMPLOYEE_ACCCOUNT (ACCOUNT_ID, EMPLOYEE_ID) values (?, ?)Using shared primary key
In this technique, hibernate will ensure that it will use a common primary key value in both the tables. This way primary key of EmployeeEntity can safely be assumed the primary key of AccountEntity also.Table structure will be like this:
In this approach, @PrimaryKeyJoinColumn is the main annotation to be used.Let see how to use it.
1.@OneToOne(cascade = CascadeType.ALL)2.@PrimaryKeyJoinColumn3.private AccountEntity account;1.@OneToOne(mappedBy="account", cascade=CascadeType.ALL)2.private EmployeeEntity employee;1.Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)2.Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)Happy Learning !!
Download source code
Source: http://howtodoinjava.com/2012/11/15/hibernate-one-to-one-mapping-using-annotations/
Tuesday, 18 February 2014
[HIBERNATE] Compound Primary Key in Hibernate
In this code how to generate a Java class for composite key (how to composite key in hibernate):
create table Time (
levelStation int(15) not null,
src varchar(100) not null,
dst varchar(100) not null,
distance int(15) not null,
price int(15) not null,
confPathID int(15) not null,
constraint ConfPath_fk foreign key(confPathID) references ConfPath(confPathID),
primary key (levelStation,ConfPathID)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
To map a composite key, you can use the EmbeddedId or the IdClass annotations. I know this question is not strictly about JPA but the rules defined by the specification also applies. So here they are:
2.1.4 Primary Keys and Entity Identity...
A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. TheEmbeddedIdandIdClassannotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15.
...
The following rules apply for composite primary keys:
- The primary key class must be public and must have a public no-arg constructor.
- If property-based access is used, the properties of the primary key class must be public or protected.
- The primary key class must be
serializable.- The primary key class must define
equalsandhashCodemethods. The semantics of value equality for these methods must be consistent with the database equality for the database types to which the key is mapped.- A composite primary key must either be represented and mapped as an embeddable class (see Section 9.1.14, “EmbeddedId Annotation”) or must be represented and mapped to multiple fields or properties of the entity class (see Section 9.1.15, “IdClass Annotation”).
- If the composite primary key class is mapped to multiple fields or properties of the entity class, the names of primary key fields or properties in the primary key class and those of the entity class must correspond and their types must be the same.
With an IdClass
IdClass
The class for the composite primary key could look like (could be a static inner class):
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, String confPathID) {
this.id = levelStation;
this.name = confPathID;
}
// equals, hashCode
}
And the entity:
@Entity
@IdClass(TimePK.class)
class Time implements Serializable {
@Id
private Integer levelStation;
@Id
private Integer confPathID;
private String src;
private String dst;
private Integer distance;
private Integer price;
// getters, setters
}
The IdClass annotation maps multiple fields to the table PK.
With EmbeddedId
The class for the composite primary key could look like (could be a static inner class):
@Embeddable
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, String confPathID) {
this.id = levelStation;
this.name = confPathID;
}
// equals, hashCode
}
And the entity:
@Entity
class Time implements Serializable {
@EmbeddedId
private TimePK timePK;
private String src;
private String dst;
private Integer distance;
private Integer price;
//...
}
The @EmbeddedId annotation maps a PK class to table PK.
Differences:
- From the physical model point of view, there are no differences
EmbeddedId somehow communicates more clearly that the key is a composite key and IMO makes sense when the combined pk is either a meaningful entity itself or it reused in your code.
@IdClass is useful to specify that some combination of fields is unique but these do not have a special meaning.
They also affect the way you write queries (making them more or less verbose):
- with
IdClass
select t.levelStation from Time t
- with
EmbeddedId
select t.timePK.levelStation from Time t
References
- JPA 1.0 specification
- Section 2.1.4 "Primary Keys and Entity Identity"
- Section 9.1.14 "EmbeddedId Annotation"
- Section 9.1.15 "IdClass Annotation"
Hibernate is really great but it definitely needs some skills and experience: knowledge of ORM concepts, mappings and relations are welcome, understanding of how the
Session works, understanding of more advanced concepts like lazy-loading, fetching strategies, caching (first-level cache, second-level cache, query cache), etc. Sure, when used correctly, Hibernate is an awesome weapon: it's efficient, it will generate better SQL queries than lots (most?) of developers, it's very powerful, it has great performances, etc. However, I've seen many project using it very badly (e.g. not using associations because they were scared to "fetch the whole database" and this is far from the worst horror) and I'm thus always a bit suspicious when I hear "we are doing Hibernate". Actually, in the wrong hands, it can be a real disaster. So, if I had to mention one weakness, it would be the learning curve. Don't underestimate it. Source: http://stackoverflow.com/questions/1607819/weaknesses-of-hibernate/1609631#1609631 |
Wednesday, 27 November 2013
How to convert java.util.date to java.sql.date?
public class MainClass {
public static void main(String[] args) {
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);
}
}
explains it. The link is http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm
Source: http://stackoverflow.com/questions/530012/how-to-convert-java-util-date-to-java-sql-date
Wednesday, 13 November 2013
Passing clicked value from jsp to jsp/servlet
We can pass the value from jsp to servlet using,
Passing clicked value from jsp to jsp/servlet:
We have to pass the clicked value as get parameter in the href link like below,
Servlet code:
In the below sample program javadomain (small letters) will be clicked, then the same value passed from jsp to servlet and there javadomain(small letters) are converted to JAVADOMAIN (UPPER CASE) then the new upper case values are passed from servlet to jsp.
Program:
main.jsp:
Output:



Source: http://javadomain.in/passing-clicked-value-from-jsp-to-jspservlet/
Thanks for reading this post……..!!!
request.getParameter("text"); //servlet code to get the jsp value
where text is the name of the input fields (text field).Passing clicked value from jsp to jsp/servlet:
We have to pass the clicked value as get parameter in the href link like below,
<a href="/Myservlet?input=javadomain">MyServlet is the name of the servlet.
Servlet code:
request.getParameter("input");
So javadomain will be passed from jsp to servlet.In the below sample program javadomain (small letters) will be clicked, then the same value passed from jsp to servlet and there javadomain(small letters) are converted to JAVADOMAIN (UPPER CASE) then the new upper case values are passed from servlet to jsp.
Program:
main.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <html> <head> <title>Small Letters</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta name="GENERATOR" content="Rational Application Developer"> </head> <body> <a href="/Blog/ToCapLetters?a=javadomain">javadomain</a> </body> </html>final.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Capital Letters</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<%
HttpSession session1 = request.getSession();
String capitalValue = session1.getAttribute("clicked_value").toString();
out.println(capitalValue);
%>
</body>
</html>
ToCapLetters.java: (servlet file)import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class ToCapLetters
*/
@WebServlet("/ToCapLetters")
public class ToCapLetters extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ToCapLetters() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String value = request.getParameter("a");
String value_capital = value.toUpperCase();
HttpSession session = request.getSession();
session.setAttribute("clicked_value", value_capital);
RequestDispatcher rd = request.getRequestDispatcher("./final.jsp");
rd.forward(request,response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
Output:
Source: http://javadomain.in/passing-clicked-value-from-jsp-to-jspservlet/
Thanks for reading this post……..!!!
Thursday, 17 October 2013
Bit Shift and ... in java
source: http://rodrigosasaki.com/2013/06/06/bit-shift-and-bitwise-operators/
Bit Shift and Bitwise Operators
Published by Rodrigo Sasaki on 06/06/2013 | Leave a response
Hello, everyone!
Today we’re gonna talk a little about Java’s Bit Shift and Bitwise operators, that allow us to work directly with binary values, which means that we’re working directly with bits
And for each of these operations we have a correspondent Java Operator. So I’ll explain the operation itself, describe how it works and then tell you the corresponding operator. Shall we?
NOT
The first operation is the easiest to understand. It’s called NOT. This is an unary operator, which means that it only has one operand, so it’s result depends entirely on a single value.
What this operation does is invert (negate) the value of a bit, and it’s quite simple, if it’s a 0 the result will be 1, and if it is an 1 the result will be 0.
The Java operator that performs this operation is the ~
We can do a quick test, when we run this code:
The printed value is: 01111111111111111111111111111111
The value you get may not have that left-hand zero, but it exists nonetheless and it’s quite important, we’ll see more about him later.
Now we can invert the printed value like this:
And now the printed value is: 10000000000000000000000000000000.
As we can see, all the 1s became 0s and the initial 0 became 1.
The result will be 1 if, and only if, both operands are 1.
We can use the following table as reference:
Based on that we can see that if either of the operands are 0, the result will also be 0.
The Java operator that performs an AND is the & and we can see that in the following example:
The result will be 1 whenever either of the operands is 1.
So what we end up with is this:
We can see that in fact if either of the operands is 1 (which means
the same is true if they both are), that will also be the result.
The Java operator responsible for performing an OR operation is the | and we can see him in action below:
The result will be 1 if, and only if, one of the operands is 1.
Pay a lot of attention to the sentence above, it basically says that it will only reaturn a 1 when both operands have different values. When they both have the same value (even if both values are 1), the result will be a 0.
Check the cheatsheet:
And there’s also a Java operator for this operation, that is the ^
You can play around with them and check all the different results,
but remember that numbers in Java are not in binary form by default, so
you may have to tinker with them a little to get the results you want.
Example: I want to know the result of an AND operation between the numbers 11010100 and 10101111, here’s the sample code for that particular operation, in version 6 of Java:
For the Java 7 version we have a syntactic sugar that allows us to do this in a more direct way. We can say that a number is in base 2 by simply adding 0b ad a prefix to our binary pattern, Like this:
We can see that the code prints 10, because the binary number 1010 when showed in decimal format is in fact 10.
So the same example as before, rewritten for Java 7 is like this:
The method Integer.toBinaryString still is necessary, because if we don’t use it, the value will be printed in base 10.
PS: If you’d like to read a bit more about number literals, you can read this.
If you think about the word Shift you’ll see that it’s a synonym to move, or dislocate. And that’s exactly what we’re about to do, dislocate bits. Fun, right?
In some moments of the explanation you may wonder: “But why am I going to want to shift a bit pattern? Where is this used in practice?”
Well, bit shifting is a very common technique applied into some more complex algorithms. As examples we have some mathematical operations (depending on your environment), CG, hash generation and so on.
To shift the bits the Java language offers urs 3 operators, and I’ll explain all of them here.
For all the operators we follow the same basic rule. The pattern to be shifted is given by the left-hand operand, and the number of bits that we’re gonna shift the pattern is given by the right-hand operand.
The first of these operators is the << that we can intuitively assume that it’ll be used to shift bits to the left, and that’s in fact what it does.
Let’s see an example:
You have the pattern 01101001 and you want to shift it one bit to the left and then see the result, so you just do it like this:
And when you print it you see the result 11010010, and you can see that it’s the same pattern, only shifted 1 bit to the left.
The problem here is related to the sign of the number, whether it’s positive or negative. To represent a negative number in base 2, we have a control bit, that is the bit that stays most to the left (remember the left bit I said was important?), so if a binary number starts with 1, we’re talking about a negative number, if it starts with a 0, we’re talking about a positive one.
An int in Java ranges from the pattern:
And the lowest number that can be represented by an int starts with a 1 followed by zeros.
So let’s get back to the operators. What’s the difference between them?
The first operator (>>) is used to shift a bit pattern to the right preserving the sign bit, which means that everything else gets shifted, but the control bit stays put. If it was a 0 it remains as 0, and if it was a 0 it remains as 1.
Now the second operator (>>>) does not preserve the sign bit, everything gets shifted, no matter where it is. And a 0 is put at the left-most bit of the pattern.
Check out the examples:
Now that’s play with it a little. In a forum I saw an user that wanted to store the information of a Date (day, month year), in a 3-byte array. Now how would he do that?
With a 3-byte array we have 24 bits to work with
Now I recommend you all play a little with this class, run tests to
try to understand what happens and why it happens, so the concepts can
really sink in.
That’s all for today. See you next time
Today we’re gonna talk a little about Java’s Bit Shift and Bitwise operators, that allow us to work directly with binary values, which means that we’re working directly with bits
What are these ‘bits’?Bit is the abbreviation to (BInary digiT), which is the smallest unit where we can store information. And as it name says, this unit can only store 2 different values, which are 0 and 1.
Bitwise
When working with these bits we can perform some operations that are called bitwise.And for each of these operations we have a correspondent Java Operator. So I’ll explain the operation itself, describe how it works and then tell you the corresponding operator. Shall we?
NOT
The first operation is the easiest to understand. It’s called NOT. This is an unary operator, which means that it only has one operand, so it’s result depends entirely on a single value.
What this operation does is invert (negate) the value of a bit, and it’s quite simple, if it’s a 0 the result will be 1, and if it is an 1 the result will be 0.
We can do a quick test, when we run this code:
public static void main(String[] args){ System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));} |
The value you get may not have that left-hand zero, but it exists nonetheless and it’s quite important, we’ll see more about him later.
Now we can invert the printed value like this:
public static void main(String[] args){ System.out.println(Integer.toBinaryString(~Integer.MAX_VALUE));} |
As we can see, all the 1s became 0s and the initial 0 became 1.
AND
This operation receives 2 values and return a result that will vary depending on these operands. We follow the basic rule:The result will be 1 if, and only if, both operands are 1.
We can use the following table as reference:
The Java operator that performs an AND is the & and we can see that in the following example:
public static void main(String[] args) { System.out.println(0 & 0); // Prints 0 System.out.println(0 & 1); // Prints 0 System.out.println(1 & 0); // Prints 0 System.out.println(1 & 1); // Prints 1} |
OR
This operation as well as the AND and the XOR (that we’ll talk about soon) receives 2 values. What changes is the condition that says if the result is 1 or 0. In this case our rule is this:The result will be 1 whenever either of the operands is 1.
So what we end up with is this:
The Java operator responsible for performing an OR operation is the | and we can see him in action below:
public static void main(String[] args){ System.out.println(0 | 0); // Prints 0 System.out.println(0 | 1); // Prints 1 System.out.println(1 | 0); // Prints 1 System.out.println(1 | 1); // Prints 1} |
XOR
The XOR usually is one of the operations that cause most confusion, because it’s usage is not as intuitive as the ones explained before, even though it’s extensively used in criptography and some other algorithms. It’s basic rule is this:The result will be 1 if, and only if, one of the operands is 1.
Pay a lot of attention to the sentence above, it basically says that it will only reaturn a 1 when both operands have different values. When they both have the same value (even if both values are 1), the result will be a 0.
Check the cheatsheet:
public static void main(String[] args){ System.out.println(0 ^ 0); // Prints 0 System.out.println(0 ^ 1); // Prints 1 System.out.println(1 ^ 0); // Prints 1 System.out.println(1 ^ 1); // Prints 0} |
Example: I want to know the result of an AND operation between the numbers 11010100 and 10101111, here’s the sample code for that particular operation, in version 6 of Java:
public static void main(String[] args){ int n1 = Integer.valueOf("11010100", 2); int n2 = Integer.valueOf("10101111", 2); System.out.println(Integer.toBinaryString(n1 & n2));} |
public static void main(String[] args){ int n = 0b1010; System.out.println(n); // Prints 10} |
So the same example as before, rewritten for Java 7 is like this:
public static void main(String[] args){ int n1 = 0b11010100; int n2 = 0b10101111; System.out.println(Integer.toBinaryString(n1 & n2));} |
PS: If you’d like to read a bit more about number literals, you can read this.
Bit Shifting
Now that you already became a bitwise machine, it’s time we give you a new tool to play with. Let’s talk a little about Bit ShiftingIf you think about the word Shift you’ll see that it’s a synonym to move, or dislocate. And that’s exactly what we’re about to do, dislocate bits. Fun, right?
In some moments of the explanation you may wonder: “But why am I going to want to shift a bit pattern? Where is this used in practice?”
Well, bit shifting is a very common technique applied into some more complex algorithms. As examples we have some mathematical operations (depending on your environment), CG, hash generation and so on.
To shift the bits the Java language offers urs 3 operators, and I’ll explain all of them here.
For all the operators we follow the same basic rule. The pattern to be shifted is given by the left-hand operand, and the number of bits that we’re gonna shift the pattern is given by the right-hand operand.
The first of these operators is the << that we can intuitively assume that it’ll be used to shift bits to the left, and that’s in fact what it does.
Let’s see an example:
You have the pattern 01101001 and you want to shift it one bit to the left and then see the result, so you just do it like this:
public static void main(String[] args){ System.out.println(Integer.toBinaryString(0b01101001 << 1));} |
01101001
<< 1
11010010
As you may have noticed, in case you want to shift it 3 bits, just send 3 as the second operand. 01101001
<< 3
1101001000
After that we have the operators that shift bits to the right, and there are 2 of those (>> and >>>), but to understand the difference between them, we need to understand some basics of how numbers work internally.The problem here is related to the sign of the number, whether it’s positive or negative. To represent a negative number in base 2, we have a control bit, that is the bit that stays most to the left (remember the left bit I said was important?), so if a binary number starts with 1, we’re talking about a negative number, if it starts with a 0, we’re talking about a positive one.
An int in Java ranges from the pattern:
10000000000000000000000000000000 (in decimal it's the number -2147483648)To the pattern:
01111111111111111111111111111111 (in decimal it's the number 2147483647)We can see that the highest number that can be represented by an int starts with a zero, which we know now that this specific zero tells us it’s a positive number.
And the lowest number that can be represented by an int starts with a 1 followed by zeros.
So let’s get back to the operators. What’s the difference between them?
The first operator (>>) is used to shift a bit pattern to the right preserving the sign bit, which means that everything else gets shifted, but the control bit stays put. If it was a 0 it remains as 0, and if it was a 0 it remains as 1.
Now the second operator (>>>) does not preserve the sign bit, everything gets shifted, no matter where it is. And a 0 is put at the left-most bit of the pattern.
Check out the examples:
10000000000000000000000000000111 >> 2 11100000000000000000000000000001 10000000000000000000000000000111 >>> 2 00100000000000000000000000000001On the first operator (>>) we can see that the 1 is preserved at the left, whilst in the second that value is shifted.
Now that’s play with it a little. In a forum I saw an user that wanted to store the information of a Date (day, month year), in a 3-byte array. Now how would he do that?
With a 3-byte array we have 24 bits to work with
00000000 00000000 00000000 byte1 byte2 byte3And the information will be divided like this:
- The first 5 bits of byte1 will store the day
- The last 3 bits of byte1 and the first bit of byte2 will store the month
- The rest of the bits will store the year
day month year 00000000 00000000 00000000 byte1 byte2 byte3All of this takes a little bit of Bit Shifting and Bitwise operations, but as a final result, we get a class like this:
public class Date{ byte[] d; public Date(){ d = new byte[3]; } public Data(int day, int month, int year){ this(); setDay(day); setMonth(month); setYear(year); } public void setDay(int day){ d[0] = (byte) (day << 3); } public int getDay(){ return d[0] >>> 3 & 0x1F; } public void setMonth(int month){ d[0] = (byte) (d[0] | month >>> 1); d[1] = (byte) (month << 7); } public int getMonth(){ return (d[0] & 0x7) << 1 | d[1] >>> 7 & 0x1; } public void setYear(int year){ d[1] = (byte) (d[1] | year >>> 8); d[2] = (byte) year; } public int getYear(){ return (d[1] << 8 & 0x7FFF) | d[2] & 0xFF; }} |
That’s all for today. See you next time
Tuesday, 8 October 2013
Java I/O
Reading and writing text files
In JDK 7, the most important classes for text files are:
- Paths and Path - file locations/names, but not their content.
- Files - operations on file content.
- StandardCharsets and Charset (an older class), for encodings of text files.
- the File.toPath method, which lets older code interact nicely with the newer java.nio API.
- Scanner - allows reading files in a compact way
- BufferedReader - readLine
- BufferedWriter - write + newLine
- it's often a good idea to use buffering (default size is 8K)
- there's always a need to pay attention to exceptions (in particular, IOException and FileNotFoundException)
In order to correctly read and write text files, you need to understand that those read/write operations always use an implicit character encoding to translate raw bytes - the 1s and 0s - into text. When a text file is saved, the tool that saves it must always use a character encoding (UTF-8 is recommended). There's a problem, however. The character encoding is not, in general, explicit: it's not saved as part of the file itself. Thus, a program that consumes a text file should know beforehand what its encoding is. If it doesn't, then the best it can do is make an assumption. Problems with encoding usually show up as weird characters in a tool that has read the file.
The FileReader and FileWriter classes are a bit tricky, since they implicitly use the system's default character encoding. If this default is not appropriate, the recommended alternatives are, for example:
FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
FileOutputStream fos = new FileOutputStream("test.txt");
OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8");
Scanner scanner = new Scanner(file, "UTF-8");
Example 1 - JDK 7+
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Scanner; public class ReadWriteTextFileJDK7 { public static void main(String... aArgs) throws IOException{ ReadWriteTextFileJDK7 text = new ReadWriteTextFileJDK7(); //treat as a small file List<String> lines = text.readSmallTextFile(FILE_NAME); log(lines); lines.add("This is a line added in code."); text.writeSmallTextFile(lines, FILE_NAME); //treat as a large file - use some buffering text.readLargerTextFile(FILE_NAME); lines = Arrays.asList("Down to the Waterline", "Water of Love"); text.writeLargerTextFile(OUTPUT_FILE_NAME, lines); } final static String FILE_NAME = "C:\\Temp\\input.txt"; final static String OUTPUT_FILE_NAME = "C:\\Temp\\output.txt"; final static Charset ENCODING = StandardCharsets.UTF_8; //For smaller files /** Note: the javadoc of Files.readAllLines says it's intended for small files. But its implementation uses buffering, so it's likely good even for fairly large files. */ List<String> readSmallTextFile(String aFileName) throws IOException { Path path = Paths.get(aFileName); return Files.readAllLines(path, ENCODING); } void writeSmallTextFile(List<String> aLines, String aFileName) throws IOException { Path path = Paths.get(aFileName); Files.write(path, aLines, ENCODING); } //For larger files void readLargerTextFile(String aFileName) throws IOException { Path path = Paths.get(aFileName); try (Scanner scanner = new Scanner(path, ENCODING.name())){ while (scanner.hasNextLine()){ //process each line in some way log(scanner.nextLine()); } } } void readLargerTextFileAlternate(String aFileName) throws IOException { Path path = Paths.get(aFileName); try (BufferedReader reader = Files.newBufferedReader(path, ENCODING)){ String line = null; while ((line = reader.readLine()) != null) { //process each line in some way log(line); } } } void writeLargerTextFile(String aFileName, List<String> aLines) throws IOException { Path path = Paths.get(aFileName); try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING)){ for(String line : aLines){ writer.write(line); writer.newLine(); } } } private static void log(Object aMsg){ System.out.println(String.valueOf(aMsg)); } }
Example 2 - JDK 7+
This example demonstrates using Scanner to read a file containing lines of structured data. One Scanner is used to read in each line, and a second Scanner is used to parse each line into a simple name-value pair. The Scanner class is only used for reading, not for writing.
import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; /** Assumes UTF-8 encoding. JDK 7+. */ public class ReadWithScanner { public static void main(String... aArgs) throws IOException { ReadWithScanner parser = new ReadWithScanner("C:\\Temp\\test.txt"); parser.processLineByLine(); log("Done."); } /** Constructor. @param aFileName full name of an existing, readable file. */ public ReadWithScanner(String aFileName){ fFilePath = Paths.get(aFileName); } /** Template method that calls {@link #processLine(String)}. */ public final void processLineByLine() throws IOException { try (Scanner scanner = new Scanner(fFilePath, ENCODING.name())){ while (scanner.hasNextLine()){ processLine(scanner.nextLine()); } } } /** Overridable method for processing lines in different ways. <P>This simple default implementation expects simple name-value pairs, separated by an '=' sign. Examples of valid input: <tt>height = 167cm</tt> <tt>mass = 65kg</tt> <tt>disposition = "grumpy"</tt> <tt>this is the name = this is the value</tt> */ protected void processLine(String aLine){ //use a second Scanner to parse the content of each line Scanner scanner = new Scanner(aLine); scanner.useDelimiter("="); if (scanner.hasNext()){ //assumes the line has a certain structure String name = scanner.next(); String value = scanner.next(); log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim())); } else { log("Empty or invalid line. Unable to process."); } } // PRIVATE private final Path fFilePath; private final static Charset ENCODING = StandardCharsets.UTF_8; private static void log(Object aObject){ System.out.println(String.valueOf(aObject)); } private String quote(String aText){ String QUOTE = "'"; return QUOTE + aText + QUOTE; } }
Example run of this class:
Name is : 'height', and Value is : '167cm' Name is : 'mass', and Value is : '65kg' Name is : 'disposition', and Value is : '"grumpy"' Name is : 'this is the name', and Value is : 'this is the value' Done.Example 3 - JDK < 7
The try-with-resources feature is not available prior to JDK 7. In this case, you need to exercise care with respect to the close method:
- it always needs to be called, or else resources will leak
- it will automatically flush the stream, if necessary
- calling close on a "wrapper" stream will automatically call close on its underlying stream
- closing a stream a second time has no consequence
- when called on a Scanner, the close operation only works if the item passed to its constructor implements Closeable. Warning: if you pass a File to a Scanner, you will not be able to close it! Try using a FileReader instead.
import java.io.*; import java.util.Scanner; /** Read and write a file using an explicit encoding. JDK 1.5. Removing the encoding from this code will simply cause the system's default encoding to be used instead. */ public final class ReadWriteTextFileWithEncoding { /** Requires two arguments - the file name, and the encoding to use. */ public static void main(String... aArgs) throws IOException { String fileName = aArgs[0]; String encoding = aArgs[1]; ReadWriteTextFileWithEncoding test = new ReadWriteTextFileWithEncoding( fileName, encoding ); test.write(); test.read(); } /** Constructor. */ ReadWriteTextFileWithEncoding(String aFileName, String aEncoding){ fEncoding = aEncoding; fFileName = aFileName; } /** Write fixed content to the given file. */ void write() throws IOException { log("Writing to file named " + fFileName + ". Encoding: " + fEncoding); Writer out = new OutputStreamWriter(new FileOutputStream(fFileName), fEncoding); try { out.write(FIXED_TEXT); } finally { out.close(); } } /** Read the contents of the given file. */ void read() throws IOException { log("Reading from file."); StringBuilder text = new StringBuilder(); String NL = System.getProperty("line.separator"); Scanner scanner = new Scanner(new FileInputStream(fFileName), fEncoding); try { while (scanner.hasNextLine()){ text.append(scanner.nextLine() + NL); } } finally{ scanner.close(); } log("Text read in: " + text); } // PRIVATE private final String fFileName; private final String fEncoding; private final String FIXED_TEXT = "But soft! what code in yonder program breaks?"; private void log(String aMessage){ System.out.println(aMessage); } }
Example 4 - JDK < 7 This example uses FileReader and FileWriter, which implicitly use the system's default encoding. It also uses buffering. To make this example compatible with JDK 1.4, just change StringBuilder to StringBuffer:
import java.io.*; /** JDK 6 or before. */ public class ReadWriteTextFile { /** * Fetch the entire contents of a text file, and return it in a String. * This style of implementation does not throw Exceptions to the caller. * * @param aFile is a file which already exists and can be read. */ static public String getContents(File aFile) { //...checks on aFile are elided StringBuilder contents = new StringBuilder(); try { //use buffering, reading one line at a time //FileReader always assumes default encoding is OK! BufferedReader input = new BufferedReader(new FileReader(aFile)); try { String line = null; //not declared within while loop /* * readLine is a bit quirky : * it returns the content of a line MINUS the newline. * it returns null only for the END of the stream. * it returns an empty String if two newlines appear in a row. */ while (( line = input.readLine()) != null){ contents.append(line); contents.append(System.getProperty("line.separator")); } } finally { input.close(); } } catch (IOException ex){ ex.printStackTrace(); } return contents.toString(); } /** * Change the contents of text file in its entirety, overwriting any * existing text. * * This style of implementation throws all exceptions to the caller. * * @param aFile is an existing file which can be written to. * @throws IllegalArgumentException if param does not comply. * @throws FileNotFoundException if the file does not exist. * @throws IOException if problem encountered during write. */ static public void setContents(File aFile, String aContents) throws FileNotFoundException, IOException { if (aFile == null) { throw new IllegalArgumentException("File should not be null."); } if (!aFile.exists()) { throw new FileNotFoundException ("File does not exist: " + aFile); } if (!aFile.isFile()) { throw new IllegalArgumentException("Should not be a directory: " + aFile); } if (!aFile.canWrite()) { throw new IllegalArgumentException("File cannot be written: " + aFile); } //use buffering Writer output = new BufferedWriter(new FileWriter(aFile)); try { //FileWriter always assumes default encoding is OK! output.write( aContents ); } finally { output.close(); } } /** Simple test harness. */ public static void main (String... aArguments) throws IOException { File testFile = new File("C:\\Temp\\blah.txt"); System.out.println("Original file contents: " + getContents(testFile)); setContents(testFile, "The content of this file has been overwritten..."); System.out.println("New file contents: " + getContents(testFile)); } }
source: http://www.javapractices.com/topic/TopicAction.do?Id=42
Subscribe to:
Posts (Atom)