How to generate unique ID that is integer in java that not guess next number?
How unique does it need to be?
If it's only unique within a process, then you can use an AtomicInteger and call incrementAndGet() each time you need a new value.
int uniqueId = 0;
int getUniqueId()
{
return uniqueId++;
}
Add synchronized if you want it to be thread safe.
import java.util.UUID;
public class IdGenerator {
public static int generateUniqueId() {
UUID idOne = UUID.randomUUID();
String str=""+idOne;
int uid=str.hashCode();
String filterStr=""+uid;
str=filterStr.replaceAll("-", "");
return Integer.parseInt(str);
}
// XXX: replace with java.util.UUID
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(generateUniqueId());
//generateUniqueId();
}
}
}
Hope this helps you.
It's easy if you are somewhat constrained.
If you have one thread, you just use uniqueID++; Be sure to store the current uniqueID when you exit.
If you have multiple threads, a common synchronized generateUniqueID method works (Implemented the same as above).
The problem is when you have many CPUs--either in a cluster or some distributed setup like a peer-to-peer game.
In that case, you can generally combine two parts to form a single number. For instance, each process that generates a unique ID can have it's own 2-byte ID number assigned and then combine it with a uniqueID++. Something like:
return (myID << 16) & uniqueID++
It can be tricky distributing the "myID" portion, but there are some ways. You can just grab one out of a centralized database, request a unique ID from a centralized server, ...
If you had a Long instead of an Int, one of the common tricks is to take the device id (UUID) of ETH0, that's guaranteed to be unique to a server--then just add on a serial number.
If you really meant integer rather than int:
Integer id = new Integer(42); // will not == any other Integer
If you want something visible outside a JVM to other processes or to the user, persistent, or a host of other considerations, then there are other approaches, but without context you are probably better off using using the built-in uniqueness of object identity within your system.
Just generate ID and check whether it is already present or not in your list of generated IDs.
UUID class
Do you need it to be;
unique between two JVMs running at
the same time.
unique even if the JVM
is restarted.
thread-safe.
support null? if not, use int or long.
if only int is required then AtomicInteger can make it possible.
if String is needed then the below code should work by mixing timeStamp and
AtomicLong.
AtomicLong idCounter = new AtomicLong(100);
long timestamp = System.currentTimeMillis();
long nextLong = idCounter.incrementAndGet();
String randomId = String.valueOf(timestamp)+String.valueOf(nextLong);
Imagine you have a class called employee with these attributes:
public class Employee {
private final String name;
private int id;
private static int nextID = 1;
public Employee(String name) {
this.name= name;
id = nextID++;
}
}
Easy peasy
Unique at any time:
int uniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
Related
I have a method for example,
public Order newOrder(Product prod, Supplier supp)
and need to generate an unique alphanumeric code with the format "ordn", where 'n' is a progressive number starting from 1, so every time a new order is added the ID will increment to "ord2" "ord3"...
How can I do this? Is it possible to do it by substringing?
I know how to generate an integer ID, but this one is a String, so my problem is more like how to increment an integer number in a string.
I tried to substring it to String ocode = "ord" + n, and just increment "n", but how can I assign this whole thing to the new order? or do I need a loop?
(the code has to be a String I guess, later there is a findOrder() method to retrieve a specific order by accepting the String code. <--not sure if it matters.)
btw I'm new to Java, and this is just a part of an exercise.
Solved, turns out the substring works...
You can use a static (tutorial) int, and increment it by 1 for each order. The current value of the static counter is the id of the current order. When you need to return the string ordn, you return "ord"+id. Here's a simple example:
public class Order {
static int sharedCounter = 0; //static, shared with ALL `Order` instances
int orderId = 0; //Specific to particular `Order` instance
public Order() {
this.orderId = sharedCounter++;
}
public String getOrderId(){
return "ord"+this.orderId;
}
}
Note that the static ids will start with zero with each execution of the program. If you're writing it as an exercise, that's probably fine; but if you need to actually generate unique ids for some orders in the real world, then you'd need to store that information somewhere, probably a database.
Also, note that I've used a shared int in the example, which isn't thread safe. If thread safety is important, you'd need an AtomicInteger
Try
String newOrderId = "ord" + (Integer.parseInt(lastOrderId.substring(3)) + 1);
I know that HashCode is a way, but I've noticed that after a while the HashCode change. So, I have an application that permit to buy things, every article is identified by a code generated by now from the hashcode and stored in the db PostgreSQL, but I have discovered this issue so I can't use it. Infact the next day that I try to identify this article on the db the hashcode changed so it doesn't works. What is a solution? Thanks a lot!
My object that generate code for article is something like this
public class AcquistoDVDRichiesto implements IsSerializable, CustomEnum {
private int codice_carrello;
private String utente;
private int numero;
private String film;
private int fornitura;
public AcquistoDVDRichiesto(){}
public AcquistoDVDRichiesto(int c, String user){
utente=user;
codice_carrello=c;
}
public void generateCodeBasket(){
if(film!=null && numero!=0 && fornitura!=0){
codice_carrello=Math.abs(film.hashCode()+((Integer)numero).hashCode()+
((Integer)fornitura).hashCode()+tipo_supporto.DVD.hashCode());
}
}
}
-
You shouldn't generate db primary keys by hand. The best approach is to let the database generate the unique primary keys for each record. This way you can be sure that there will be no primary key collisions and the codes will not change.
In PostreSQL, you can use a SERIAL column type to achieve that. Example:
CREATE TABLE tablename (
colname SERIAL
);
The other way is to use a sequence, but it is a bit more complicated.
I want to keep two things in my priority queue...one is a number and the other is cost. i.e. I want to do the following:
PriorityQueue<Integer, Cost> q=new PriorityQueue<Integer, Cost>();
Cost is another class that i hav:
class Cost implements Comparable<Cost>
{
String name;
double cost;
#Override
public int compareTo(Cost s)
{
return Double.compare(cost, s.cost);
}
}
Also I want to perform comparisons only based on cost...but I also want some integer identifier to be passed along with cost...is there some way to achieve this?
i need to retrieve Cost based on id..therefore I am using a hash map for it. When using an id field in cost...i want to retrieve the entire cost instance based on that id field...is it possible...is yes, then how?
I am a novice at Java programming. Can someone pls suggest some way out?
Change your Cost class
public class Cost implements Comparable<Cost> {
String name;
double cost;
int id;
public Cost(int id, String name, double cost) {
this.id = id;
this.name = name;
this.cost = cost;
}
#Override
public int compareTo(Cost s) {
return Double.compare(cost, s.cost);
}
public int getId() {
return this.id;
}
#Override
public String toString() {
return new StringBuilder().append("id : ").append(id).append(
" name: ").append(name).append(" cost :").append(cost)
.toString();
}
}
Then you can simply declare PriorityQueue of Const
PriorityQueue<Cost> q=new PriorityQueue<Cost>();
Now when you want to find Cost based on id you can do below
PriorityQueue<Cost> queue = new PriorityQueue<Cost>();
queue.add(new Cost(1, "one", 1));
queue.add(new Cost(2, "two", 2));
int id = 2;// Id to be found
for (Cost cost : queue) {
if (cost.getId() == 2) {
System.out.println(cost);
}
}
The Cost object is a good start. Make an object that contains both an integer and a Cost, and put those in the priority queue. Or, add an integer field to the Cost class itself.
You may want to wrap your integer and cost in a Map/HashMap as below:
PriorityQueue<Map<Integer, Cost>> q = new PriorityQueue<Map<Integer, Cost>>();
Now you would be able to create a HashMap object and put you two object in that before putting in the queue.
Also, you want to create a custom wrapper Class e.g. CostNumber which will have Integer and Cost as two member variables. Once done ,you can use that new object in the queue.
Since PriorityQueue stores a single object, you need to do one of the following:
create a class that contains both the integer and the cost object, iff integer and cost are unrelated.
push the integer attribute as another member of Cost class iff they are related.
Also I want to perform comparisons only based on cost...but I also want some integer identifier to be passed along with cost...is there some way to achieve this?
Why would you want to pass something to compareTo that you are not going to use during comparison? In any case, the signature of this method cannot be changed if you want to leverage the Comparator framework. You can add that integer identifier to your Cost class itself as another member and thereby make it available during compareTo method execution.
I'm doing a school project in Java and I the following question have arisen:
I have an entity with attributes - id, name, phone.. with id as the unique primary key. I want to store them in a data structure(such as list..). Then in the application I obtain the data for creating a new instance (name, phone..) and I want to create a new instance of the entity and store it in my data structure with a new unique id. The id shouldn't be random, it would be best if the id rised continuously with the size of the list. Also I dont want to reuse ids.
The first implementation that comes to my mind is to use ArrayList and simply set id as indexes. But ArrayList.remove(int index) after removal shifts all following elements to left. I assume that ArrayList.remove(Object o) works the same, but i would be gratefull i I'm proven wrong. Determining ids from last element would not work either. I could go through all of them but that seems inefiicient.
Thanks in advance for any help :)
You want to keep a counter for them. You could use a static value in the class (you may need to synchronize it for multi-threaded classes.)
import java.util.concurrent.atomic.AtomicInteger;
class MyClass {
// thread safe
private static final AtomicInteger safeCounter = new AtomicInteger();
private final int uniqueId; // can never change uniqueId
private String name; // the data of the class
public MyClass(String name) {
this.name = name;
this.uniqueId = MyClass.safeCounter.getAndIncrement();
}
public boolean equals(Object o) {
if(o instanceof MyClass) { // instanceof also does null check :-)
MyClass mc = (MyClass)o;
return mc.uniqueId == this.uniqueId;
}
return false;
}
public int hashCode() {
return uniqueId;
}
}
If this is for homework, or if threadsafety isn't a concern, you can use a simple static int
class MyClass {
private static int nextUniqueId() {
int result = counter;
counter++;
return result;
}
// not thread safe
private static int counter;
private final int uniqueId; // can never change uniqueId
private String name; // the data of the class
public MyClass(String name) {
this.name = name;
this.uniqueId = nextUniqueId();
}
public boolean equals(Object o) {
if(o instanceof MyClass) { // instanceof also does null check :-)
MyClass mc = (MyClass)o;
return mc.uniqueId == this.uniqueId;
}
return false;
}
public int hashCode() {
return uniqueId;
}
}
How about using a Factory that users a Strategy for generating your identifiers?
Edited to answer question about factories
A Factory is a design pattern that is used to encapsulate the creation of different types of Objects. A Strategy is another design pattern that is used to encapsulate the behavior of specific business logic that might have different rules or that might change over time.
In your case you clearly require a new Identifier for each object that needs to be unique. You also stated in your question comments above that eventually you will be storing your objects in a database, which also would most likely require you to get your identifier from your database in the long run.
Here is a smallish example of using a Factory to create your User Objects instead of just using new(). Please kindly disregard any spelling or compile mistakes, I wrote the following code with out the assistance of a compiler or IDE.
public interface UserFactory {
User createUser();
}
public interface IdentifierStrategy {
// I just picked Long for ease of use.
Long getIdentifier();
}
public class UserFactoryImpl {
private final IdentifierStrategy identifierStrategy;
public UserFactoryImpl(final IdentifierStrategy identifierStrategy) {
this.identifierStrategy = identifierStrategy;
}
public User createUser() {
Long identifier = this.identifierStrategy.getIdentifier();
User user = new User(identifier);
return user;
}
}
public class LongIdentifierStrategy implements IdentifierStrategy {
public Long getIdentifier() {
// Do something here that will return a unique long.
Long long = new Long(1);
return long;
}
}
// In the long term, you would most likely use this IdentiferStrategy
// to get your identifiers from the database.
public class JDBCIdentifierStrategy implements IdentifierStrategy {
public Long getIdentifer() {
// Get a jdbc connection from a jdbc connection pool.
// Get the next identifier from the databsae.
Long long = new Long(1);
return long;
}
}
Now, in the long run, if your requirement change for how you need to identifier your User objects, you would only need to write a new IdentifierStrategy and update your UserFactoryImpl with that new Strategy.
One important question: what's the scope of the uniqueness?
Just for the duration of a run of the application? Do you have a single thread or multiple threads, so unique across those threads? Or could there be several copies of the app running at the same time, so unique across all instances, even across many machines? Will you save the data somewhere and so need uniqueness across future runs of the program too?
Two fundamental schemes:
a). use a database, they usually offer some kind of auto-generated primary key: you insert the record, it gives you a unique key.
b). generate the key yourself, in this case: first isolate the key generation to it's own class, then you can make the generation as clever as you wish. Sketch:
some initialisation, generate an initial value, simple case it's zero, or it derives from the current date/time, or MAC address of your machine, or whatever
provide a getNextId() function, which probably needs to be synchronized if threads are involved.
A very simple scheme, which will be OK for low volume systems, just use
new Date().getTime();
You can also look for GUID generators, which produce something unique, but rather bigger than an int.
My suggestion is to have an Object Pooling for ID generation. When the entity is "deleted", the ID should be returned to the pool, and when needing a new ID, the pool should either
Give you a new ID (if old ID doesn't exists in pool) or
Create a new ID for an entity.
The problem is that you will have to create an entity management system that caters for returning the "used" ID to the pool if entity is "deleted" (bear in mind the multithreading environment, which you will need to manage).
Alternatively, use a database system which provides primary key generation (most uses AUTO_INCREMENT).
My GWT application creates text areas, each of which must have an ID in order to be useful to a third-party JavaScript library. I know how to assign an ID to a GWT widget; I'm after a good way of generating those unique ID's.
For GWT, take a look at HTMLPanel.createUniqueId
String id = HTMLPanel.createUniqueId();
I believe this would be what you need for unique identifiers ( using a timestamp and the 'widget-' namespace ).
'widget-' + (new Date).valueOf()
Java has a built-in class for unique ID creation: http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html
Another common way is by using a timestamp, i.e. System.currentTimeMillis()
Javascript:
var idIndex = 0;
function getNewId() {
return "textGWT"+(idIndex++);
}
Java:
class IdMaker {
private static int idIndex = 0;
public static String generate() {
return "textGWT"+(idIndex++);
}
}