I have two issues here. Let me describe the goal of the program first. I simply want to populate a company_id row of my table with 100000 string ids ranging from 00000-99999, shuffled, with no repeats. I was successful in creating an array like this. Now, I am trying to fill my primary key column with this array. As seen in my code below, I am trying to do this with a for loop. I am new to MySQL, so I am unsure if this is an efficient way to insert an array into a column. The first issue is that only 1000 strings are entered. The second issue is that it sorts the strings by number (00000, 00001, etc). My code is below. Any ideas? Thanks.
Update:
I solved one of the issues. I was silly enough to think that it would show the table in it's entirety. I simply went to MySQLWorkbench > Preferences > SQL Execution > Limit Rows Count. Still don't understand why it is automatically sorting my table by primary key.
package populateDB;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Random;
public class PopulateDB {
public static void main(String[] args) {
int[] nums = new int[100000];
String[] ids = new String[100000];
// Fill array with numbers 0-99999
for(int i = 0; i < ids.length; i++) {
nums[i] = i;
}
// Fill array to give length
Arrays.fill(ids, "fill");
shuffleArray(nums);
// Changes numbers such as 235 to 00235
for(int i = 0; i < ids.length; i++) {
ids[i] = createString(nums[i]);
}
try
{
// Create a MySQL database connection
String myDriver = "org.gjt.mm.mysql.Driver";
String myUrl = "jdbc:mysql://localhost:3306/humansight_schema";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(myUrl, "root", "password");
// The MySQL insert statement
String query = " insert into user_data (company_id)"
+ " values (?)";
for(int i = 0; i < ids.length; i++) {
// Create the MySQL insert PreparedStatement
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString (1, ids[i]);
// Execute the PreparedStatement
preparedStmt.execute();
}
conn.close();
System.out.println("Done");
}
catch (Exception e)
{
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
}
private static void shuffleArray(int[] array)
{
int index;
Random random = new Random();
for (int i = array.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
if (index != i)
{
array[index] ^= array[i];
array[i] ^= array[index];
array[index] ^= array[i];
}
}
}
private static String createString(int num) {
String numString = Integer.toString(num);
int zeroesToAdd = 5 - numString.length();
String zeroes = "";
for(int i = 0; i < zeroesToAdd; i++) {
zeroes = zeroes.concat("0");
}
return zeroes.concat(numString);
}
}
Related
I have connect Processing and SQL by using database library "de.Bezier.data.sql".
I don't know How can I get the name of columns in a specific Table.
I get the correct name of database, but i got the following as result of name of columns "Tables_in_sql7363100"
import de.bezier.data.sql.*;
MySQL sql;
String[] tableNames;
String[] columnNames;
void setup() {
size(300, 300);
database_connection();
if (connect) {
tableNames = sql.getTableNames();
for (int i=0; i<tableNames.length; i++) {
println(tableNames[i]);
}
columnNames = sql.getColumnNames();
for (int i=0; i<ColumnNames.length; i++) {
println(columnNames[i]);
}
}
}
void draw() {
background(255);
}
void database_connection() {
sql = new MySQL(this, "ServerName", "DataBase", "DUN", "PW");
if (sql.connect()) {
connect = true;
connect_status = "Conected";
} else {
connect = false;
connect_status = "Connection Failed";
}
}
There are 2 problems with what I'm seeing. The first one, which interests you, is that you didn't select any table. That's why you don't get a list of columns. You can fix this by using a simple query:
sql.query("SELECT * FROM myTable");
But that's not the only thing: you're not accounting for lag. It may work for now on a local database because lag is really low, but this won't fly with something which is over the internet. Here's an example where I show columns from a public test database and how long it takes to get the result from my query back:
import de.bezier.data.sql.*;
MySQL sql;
String user = "rfamro";
String pass = "";
String server = "mysql-rfam-public.ebi.ac.uk:4497";
String database = "Rfam";
String[] columnNames;
void setup() {
size(300, 300);
sql = new MySQL(this, server, database, user, pass);
}
void draw() {
if (columnNames != null) {
println("It took " + millis() + "ms to get this data back.");
for (String s : columnNames) {
println(s);
}
noLoop();
} else if (sql.connect()) {
sql.query("SELECT * FROM family");
sql.next(); // only use .next when you know you have data
columnNames = sql.getColumnNames();
}
}
From here, it takes between 2-7 seconds to get the data back. You'll understand that, the setup() method running taking about a couple milliseconds, you won't have any results back by then.
Hope this helps. Have fun!
I managed to retrieve the SQLite table with only the first item of the array and put it in the UI's TextView. Couldn't get all the of the array's items. From each of the rest of the columns, a single value is returned successfully.
The JSON is parsed and passed as a parcelable ArrayList to a Fragment where it's presented in a list. Clicking on a list item directs to another Fragment where all the of item's details are presented.
I've been trying to write a for loop that returns the Strings in the array into the TextView, but the condition i < genresList.size() is always false. I tried using a while loop, but it returns only the first item of the list.
Various ways I've found on the internet didn't work.
Thanks.
Parsing and insertion to SQLite
private void parseJsonAndInsertToSQLIte(SQLiteDatabase db) throws JSONException {
// parsing the json
String jsonString = getJsonFileData();
JSONArray moviesArray = new JSONArray(jsonString);
ContentValues insertValues;
for (int i = 0; i < moviesArray.length(); i++) {
JSONObject jsonObject = moviesArray.getJSONObject(i);
String title = jsonObject.getString("title");
String imageUrl = jsonObject.getString("image");
String rating = jsonObject.getString("rating");
String releaseYear = jsonObject.getString("releaseYear");
JSONArray genresArray = jsonObject.getJSONArray("genre");
List<String> genres = new ArrayList<>();
for (int k = 0; k < genresArray.length(); k++) {
genres.add(genresArray.getString(k));
}
insertValues = new ContentValues();
insertValues.put(Movie.TITLE, title);
insertValues.put(Movie.IMAGE_URL, imageUrl);
insertValues.put(Movie.RATING, rating);
insertValues.put(Movie.RELEASE_YEAR, releaseYear);
for (int k = 0; k < genresArray.length(); k++) {
insertValues.put(Movie.GENRE, genres.get(k));
}
Log.i(TAG, "insertValues: " + genresArray);
long res = db.insert(TABLE_NAME, null, insertValues);
Log.i(TAG, "parsed and inserted to sql - row: " + res);
}
}
The item's details Fragment
public class MovieDetailsFragment extends Fragment{
... variables declarations come here...
#Nullable
#Override
public View onCreateView(#NotNull LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_details_movie, container, false);
Context context = getActivity();
Bundle idBundle = getArguments();
if (idBundle != null) {
movieId = getArguments().getInt("id");
}
getDatabase = new GetDatabase(context);
getDatabase.open();
Cursor cursor = getDatabase.getMovieDetails(movieId);
... more irelevant code comes here...
titleView = rootView.findViewById(R.id.movieTtlId);
ratingView = rootView.findViewById(R.id.ratingId);
releaseYearView = rootView.findViewById(R.id.releaseYearId);
genreView = rootView.findViewById(R.id.genreID);
String titleFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.TITLE));
String ratingFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RATING));
String releaseYearFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RELEASE_YEAR));
String genreFromSQLite;
if(cursor.moveToFirst()) {
do {
genreFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
genres.add(genreFromSQLite);
} while (cursor.moveToNext());
}
else{
genreFromSQLite = cursor.getString(cursor.getColumnIndex(Movie.RELEASE_YEAR));
}
getDatabase.close();
//more irelevant code comes here
genreView.setText(genreFromSQLite);
genreView.setFocusable(false);
genreView.setClickable(false);
return rootView;
}
}
The method that returns the table from SQLite:
public ArrayList<Movie> getMovies() {
String[] columns = {
Movie.ID,
Movie.TITLE,
Movie.IMAGE_URL,
Movie.RATING,
Movie.RELEASE_YEAR,
Movie.GENRE
};
// sorting orders
String sortOrder =
Movie.RELEASE_YEAR + " ASC";
ArrayList<Movie> moviesList = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME, //Table to query
columns,
null,
null,
null,
null,
sortOrder);
if (cursor.moveToFirst()) {
do {
Movie movie = new Movie();
movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
List<String> genreArray = new ArrayList<>();
while(cursor.moveToNext()){
String genre = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
genreArray.add(genre);
}
movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));
// Adding a movie to the list
moviesList.add(movie);
} while (cursor.moveToNext());
}
Log.d(TAG, "The movies list from sqlite: " + moviesList);
cursor.close();
db.close();
return moviesList;
}
I believe your issue is with :-
for (int k = 0; k < genresArray.length(); k++) {
insertValues.put(Movie.GENRE, genres.get(k));
}
That will result in just the last value in the loop being inserted as the key/column name (first parameter of the put) does not change (and probably can't as you only have the one column).
You could use :-
StringBuilder sb = new StringBuilder();
for (int k = 0; k < genresArray.length(); k++) {
if (k > 0) {
sb.append(",");
}
sb.append(genres.get(k));
}
insertValues.put(Movie.GENRE, sb.toString());
Note the above code is in-principle code. It has not been tested or run and may therefore contains errors.
This would insert all the data as a CSV into the GENRE column.
BUT that is not a very good way as far as utilising databases. It would be far better if the Genre's were a separate table and probably that a mapping table were used (but that should be another question).
This is going to cause you issues as well :-
if (cursor.moveToFirst()) {
do {
Movie movie = new Movie();
movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
List<String> genreArray = new ArrayList<>();
while(cursor.moveToNext()){
String genre = cursor.getString(cursor.getColumnIndex(Movie.GENRE));
genreArray.add(genre);
}
movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));
// Adding a movie to the list
moviesList.add(movie);
} while (cursor.moveToNext());
That is you move to the first row of the Cursor, extract some data MoveieId,Title ... ReleaseYear.
Then
a) if there any other rows you move to the next (which would be for a different Movie) and the next until you finally reached the last row adding elements to the genreArray.
or
b) If there is only the one row in the Cursor genreArray is empty.
You then add the 1 and only movie to the movieList and return.
1 move (row) in the Cursor will exist per movie and there is only the 1 GENRE column per movie. You have to extract the data in that column and then split the data into the genreArray without moving (see the previous fix that will create a CSV (note that would be messed up if the data contained commas)).
IF you used the previous fix and store the multiple genres as a CSV, then you could use :-
if (cursor.moveToFirst()) {
do {
Movie movie = new Movie();
movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
List<String> genreArray = new List<>(Arrays.asList((cursor.getString(cursor.getColumnIndex(Movie.GENRE))).split(",",0)));
movie.setGenre(Collections.singletonList(String.valueOf(genreArray)));
// Adding a movie to the list
moviesList.add(movie);
} while (cursor.moveToNext());
Note the above code is in-principle code. It has not been tested or run and may therefore contains errors.
In my JavaFx application, i'm loading an ObservableList when a button is clicked and then display the list in a table.
the controller code:
#FXML
private void initialize() throws SQLException, ParseException, ClassNotFoundException {
searchChoice.setItems(criteriaList);
searchChoice.getSelectionModel().selectFirst();
productIdColumn.setCellValueFactory(cellData -> cellData.getValue().productIdProperty());
unitColumn.setCellValueFactory(cellData -> cellData.getValue().unitProperty());
productTitleColumn.setCellValueFactory(cellData -> cellData.getValue().titleProperty());
productTypeColumn.setCellValueFactory(cellData -> cellData.getValue().typeProperty());
productUnitPriceColumn.setCellValueFactory(cellData -> Bindings.format("%.2f", cellData.getValue().unitPriceProperty().asObject()));
productQuantityColumn.setCellValueFactory(cellData -> cellData.getValue().quantityProperty().asObject());
productStatusColumn.setCellValueFactory(cellData -> cellData.getValue().productStatusProperty());
descriptionColumn.setCellValueFactory(cellData -> cellData.getValue().descriptionProperty());
reorderPointColumn.setCellValueFactory(cellData -> cellData.getValue().reOrderPointProperty().asObject());
surplusPointColumn.setCellValueFactory(cellData -> cellData.getValue().surplusPointProperty().asObject());
productIdColumn.setSortType(TableColumn.SortType.DESCENDING);
productTable.getSortOrder().add(productIdColumn);
productTable.setRowFactory(tv -> new TableRow<Product>() {
#Override
public void updateItem(Product item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setStyle("");
} else if (item.getQuantity() < item.getReOrderPoint()) {
setStyle("-fx-background-color: tomato;");
} else if (item.getQuantity() > item.getSurplusPoint()) {
setStyle("-fx-background-color: darkorange;");
} else {
setStyle("-fx-background-color: skyblue;");
}
}
});
try {
ObservableList<Product> productData = ProductDAO.searchProducts();
populateProducts(productData);
String[] expireDate = new String[productData.size()];
String[] id = new String[productData.size()];
String[] existingStatus = new String[productData.size()];
for (int i = 0; i < productData.size(); i++) {
expireDate[i] = productData.get(i).getExpireDate();
id[i] = productData.get(i).getProductId();
existingStatus[i] = productData.get(i).getProductStatus();
DateFormat format = new SimpleDateFormat(app.values.getProperty("DATE_FORMAT_PATTERN"), Locale.ENGLISH);
Date expireDateString = format.parse(expireDate[i]);
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date today = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
if (expireDateString.before(today) && !existingStatus[i].equals(app.values.getProperty("STATUS_TYPE2"))) {
ProductDAO.updateProductStatus(id[i], app.values.getProperty("STATUS_TYPE3"));
}
if (expireDateString.after(today) && !existingStatus[i].equals(app.values.getProperty("STATUS_TYPE2"))) {
ProductDAO.updateProductStatus(id[i], app.values.getProperty("STATUS_TYPE1"));
}
}
ObservableList<Product> productDataRefreshed = ProductDAO.searchProducts();
populateProducts(productDataRefreshed);
ObservableList<Product> productCodesData = ProductDAO.getProductCodes();
ObservableList<Product> productTitlesData = ProductDAO.getProductTitles();
ObservableList<Product> productTypesData = ProductDAO.getProductTypes();
ObservableList<Product> productStatusData = ProductDAO.getProductStatus();
String possibleProducts1[] = new String[productCodesData.size()];
for (int k = 0; k < productCodesData.size(); k++) {
possibleProducts1[k] = productCodesData.get(k).getProductId();
}
String possibleProducts2[] = new String[productTitlesData.size()];
for (int k = 0; k < productTitlesData.size(); k++) {
possibleProducts2[k] = productTitlesData.get(k).getTitle();
}
String possibleProducts3[] = new String[productTypesData.size()];
for (int k = 0; k < productTypesData.size(); k++) {
possibleProducts3[k] = productTypesData.get(k).getType();
}
String possibleProducts4[] = new String[productStatusData.size()];
for (int k = 0; k < productStatusData.size(); k++) {
possibleProducts4[k] = productStatusData.get(k).getProductStatus();
}
TextFields.bindAutoCompletion(searchField, possibleProducts1);
TextFields.bindAutoCompletion(searchField, possibleProducts2);
TextFields.bindAutoCompletion(searchField, possibleProducts3);
TextFields.bindAutoCompletion(searchField, possibleProducts4);
} catch (SQLException e) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle(app.values.getProperty("ERROR_TITLE"));
alert.setHeaderText(app.values.getProperty("FAILURE_MESSAGE"));
alert.setHeaderText(app.values.getProperty("ERROR_GETTING_INFORMATION_FROM_DATABASE_MESSAGE"));
alert.showAndWait();
throw e;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
the service mysql query :
public static ObservableList<Product> searchProducts() throws SQLException, ClassNotFoundException {
String selectStmt = "SELECT * FROM product";
ResultSet rsPrdcts = DbUtil.dbExecuteQuery(selectStmt);
ObservableList<Product> productList = getProductList(rsPrdcts);
return productList;
}
The issue here is, when there are more than 200-300 items in the list the scene gets really slow to load. What countermeasures can I take regarding this matter? Any idea will be very much appreciated.
Thanks in advance.
You need to implement an ObservableList which only retrieves the data which is rqeusted by the TableView. Currently you retrive all elements in the table and cast the retrieved list to an ObservableList.
The TableView uses the .get(int idx) method of the OL to retrieve all items which should be displayed and the .size() method for determining the size of the scrollbar. When you scroll the TableView will discard all items which are not displayed and call the get method again.
To solve your problem need to create a class which implements ObservableList<E>. First you need to implement the .get(int idx) and the .size() method, for all other methods I would throw new UnsupportedOperationException() and later on see which other method is needed. So the .size() method needs to execute the following query
SELECT count(*) FROM product
and the get(int idx) something like this
int numItems = 30;
int offset = idx - (idx % numItems)
SELECT * FROM product LIMIT offset, numItems
you can create an internal list which only holds e.g. 30 items from your db and whenever the requested idx < offset || idx > offset + numItems you issue a new db request.
I used this this approach with database tables with millions of rows and had a very performant GUI. You can also add paging to the TableView because with to many rows the scrollbar gets useless, but this is a different discussion.
edit:
I forgot to mention that this is called Lazy Loading
I try to select a row from jTable and store the value into topicId. Here are my codes.
jTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
if (jTable.getSelectedRow() >= 0 && jTable.getValueAt(jTable.getSelectedRow(), 0) != null) {
topicId = (Integer)jTable.getValueAt(jTable.getSelectedRow(), 0);}
System.out.println(topicId);
eForumTopics topics = new eForumTopics(topicId);
topics.retrieveThread();
getJFrame().dispose();
eForumThreadContent myWindow = new eForumThreadContent(topicId);
myWindow.getJFrame().setVisible(true);
}
});
}
Here are my codes for scroll pane.
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setBounds(new Rectangle(75, 220, 800, 450));
jScrollPane.setViewportView(getJTable());
}
return jScrollPane;
}
And here are the codes for jTable.
private JTable getJTable() {
if (jTable == null) {
Vector columnNames = new Vector(); // Vector class allows dynamic
// array of objects
Vector data = new Vector();
try {
DBController db = new DBController();
db.setUp("IT Innovation Project");
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String dsn = "IT Innovation Project";
String s = "jdbc:odbc:" + dsn;
Connection con = DriverManager.getConnection(s, "", "");
String sql = "Select topic_title,topic_description,topic_by from forumTopics WHERE topic_category = '"+category+"'";
java.sql.Statement statement = con.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
ResultSetMetaData metaData = resultSet.getMetaData();
int columns = metaData.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(metaData.getColumnName(i));
}
while (resultSet.next()) {
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(resultSet.getObject(i));
}
data.addElement(row);
}
resultSet.close();
((Connection) statement).close();
} catch (Exception e) {
System.out.println(e);
}
jTable = new JTable(data, columnNames);
TableColumn column;
for (int i = 0; i < jTable.getColumnCount(); i++) {
column = jTable.getColumnModel().getColumn(i);
if (i == 1) {
column.setPreferredWidth(400); // second column is bigger
}else {
column.setPreferredWidth(200);
}
}
String header[] = { "Title", "Description", "Posted by" };
for (int i = 0; i < jTable.getColumnCount(); i++) {
TableColumn column1 = jTable.getTableHeader().getColumnModel()
.getColumn(i);
column1.setHeaderValue(header[i]);
}
jTable.getTableHeader().setFont( new Font( "Dialog" , Font.PLAIN, 20 ));
jTable.getTableHeader().setForeground(Color.white);
jTable.getTableHeader().setBackground(new Color(102, 102, 102));
jTable.setEnabled(false);
jTable.setRowHeight(100);
jTable.getRowHeight();
jTable.setFont( new Font( "Dialog" , Font.PLAIN, 18 ));
jTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
I not sure whether is my table or scroll pane got problem. Whenever I selected any rows in the jTable, for example, 4 or 5 or 6, the result keep returning me row 0. Somebody can help? Thanks in advance.
There is no point in adding a mouse listener to store the selected row in a field. The table knows its selected row(s), and moreover, the selection can change without using the mouse.
If you want to do something (like loading details of a selected row) each time the selection changes, then add a selection listener:
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = table.getSelectedRow();
if (viewRow >= 0) {
int modelRow = table.convertRowIndexToModel();
Integer topicId = tableModel.getTopicIdAtRow(modelRow);
// todo load the details for topicId
}
}
}
});
Does anyone knows how to convert decimal notation of an IP address into binary form in Java? Please let me know...
An IP address written as a.b.c.d can be converted to a 32-bit integer value
using shift and bit-wise inclusive OR operators as,
(a << 24) | (b << 16) | (c << 8) | d
To be safe, each of a,b,c,d has valid range 0-255 -- you can check that in your conversion.
You can further validate the IP address using this regex example.
You can use the java.net.InetAddress class. Two methods you should look at are getByName and getAddress. Here is a simple code example
import java.net.InetAddress;
import java.net.UnknownHostException;
/* ... */
String ip = "192.168.1.1";
InetAddress address = null;
try {
address = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
//Your String wasn't a valid IP Address or host name
}
byte [] binaryIP = address.getAddress();
Gathering your suggestions and some other sources, I found usefull to convert an InetAdress to an array of bit, as well as BitSet, which can help to compute and(), or(), xor() out of your binary representation.
Following sample shows how to convert ip to binary and binary to ip.
Enjoy!
public class IpConverter {
public static void main(String[] args) {
String source = "192.168.1.1";
InetAddress ip = null;
try {
ip = InetAddress.getByName(source);
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
System.out.println( "source : " + ip);
// To bit sequence ------------
byte[] binaryIP = ip.getAddress();
BitSet[] bitsets = new BitSet[binaryIP.length];
int k = 0;
System.out.print("to binary: ");
for (byte b : binaryIP) {
bitsets[k] = byteToBitSet(b);
System.out.print( toString( bitsets[k] ) + ".");
k++;
}
System.out.println();
// Back to InetAdress ---------
byte[] binaryIP2 = new byte[4];
k = 0;
for (BitSet b : bitsets) {
binaryIP2[k] = bitSetToByte(b);
k++;
}
InetAddress ip2 = null;
try {
ip2 = InetAddress.getByAddress(binaryIP2);
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
System.out.println( "flipped back to : " + ip2);
}
public static BitSet byteToBitSet(byte b) {
BitSet bits = new BitSet(8);
for (int i = 0; i < 8; i++) {
bits.set(i, ((b & (1 << i)) != 0) );
}
return bits;
}
public static byte bitSetToByte(BitSet bits) {
int value = 0;
for (int i = 0; i < 8; i++) {
if (bits.get(i) == true) {
value = value | (1 << i);
}
}
return (byte) value;
}
public static byte bitsToByte(boolean[] bits) {
int value = 0;
for (int i = 0; i < 8; i++) {
if (bits[i] == true) {
value = value | (1 << i);
}
}
return (byte) value;
}
public static boolean[] byteToBits(byte b) {
boolean[] bits = new boolean[8];
for (int i = 0; i < bits.length; i++) {
bits[i] = ((b & (1 << i)) != 0);
}
return bits;
}
public static String toString(BitSet bits){
String out = "";
for (int i = 0; i < 8; i++) {
out += bits.get(i)?"1":"0";
}
return out;
}
}
The open-source IPAddress Java library can do this for you. It can parse various IP address formats, including either IPv4 or IPv6, and has methods to produce various string formats, including one for binary. Disclaimer: I am the project manager of the IPAddress library.
This code will do it:
static void convert(String str) {
IPAddressString string = new IPAddressString(str);
IPAddress addr = string.getAddress();
System.out.println(addr + " in binary is " + addr.toBinaryString());
}
Example:
convert("1.2.3.4");
convert("a:b:c:d:e:f:a:b");
The output is:
1.2.3.4 in binary is 00000001000000100000001100000100
a:b:c:d:e:f:a:b in binary is 00000000000010100000000000001011000000000000110000000000000011010000000000001110000000000000111100000000000010100000000000001011