yao000 发表于 2017-12-16 12:03:57

生成类似于MongoDB产生的ObjectId

package com.jt.boot.utils;  

  
import com.google.common.base.Objects;
  

  
import java.net.NetworkInterface;
  
import java.nio.ByteBuffer;
  
import java.util.Date;
  
import java.util.Enumeration;
  
import java.util.Random;
  
import java.util.concurrent.atomic.AtomicInteger;
  
import java.util.logging.Level;
  
import java.util.logging.Logger;
  

  
/**

  
* <p>A globally unique>  
* <p/>
  
* <p>Consists of 12 bytes, divided as follows:</p>
  
* <table border="1">
  
* <caption>ObjectID layout</caption>
  
* <tr>
  
* <td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td>
  
* </tr>
  
* <tr>
  
* <td colspan="4">time</td><td colspan="3">machine</td> <td colspan="2">pid</td><td colspan="3">inc</td>
  
* </tr>
  
* </table>
  
* <p/>

  
* <p>Instances of this>  
*/

  
public>  

  
   private final int _time;
  
   private final int _machine;
  
   private final int _inc;
  
   private boolean _new;
  
   private static final int _genmachine;
  

  
   private static AtomicInteger _nextInc = new AtomicInteger((new Random()).nextInt());
  

  
   private static final long serialVersionUID = -4415279469780082174L;
  

  
   private static final Logger LOGGER = Logger.getLogger("org.bson.ObjectId");
  

  
   /**

  
      * Create a new object>  
      */
  
   public ObjectId() {
  
         _time = (int) (System.currentTimeMillis() / 1000);
  
         _machine = _genmachine;
  
         _inc = _nextInc.getAndIncrement();
  
         _new = true;
  
   }
  
   

  
   public static String>  
         return get().toHexString();
  
   }
  

  
   /**

  
      * Gets a new object>  
      *

  
      * @return the new>  
      */
  
   public static ObjectId get() {
  
         return new ObjectId();
  
   }
  

  
   /**
  
      * Checks if a string could be an {@code ObjectId}.
  
      *
  
      * @param s a potential ObjectId as a String.

  
      * @return whether the string could be an object>  
      * @throws IllegalArgumentException if hexString is null
  
      */
  
   public static boolean isValid(String s) {
  
         if (s == null)
  
             return false;
  

  
         final int len = s.length();
  
         if (len != 24)
  
             return false;
  

  
         for (int i = 0; i < len; i++) {
  
             char c = s.charAt(i);
  
             if (c >= '0' && c <= '9')
  
               continue;
  
             if (c >= 'a' && c <= 'f')
  
               continue;
  
             if (c >= 'A' && c <= 'F')
  
               continue;
  

  
             return false;
  
         }
  

  
         return true;
  
   }
  

  

  
   /**
  
      * Converts this instance into a 24-byte hexadecimal string representation.
  
      *
  
      * @return a string representation of the ObjectId in hexadecimal format
  
      */
  
   public String toHexString() {
  
         final StringBuilder buf = new StringBuilder(24);
  
         for (final byte b : toByteArray()) {
  
             buf.append(String.format("%02x", b & 0xff));
  
         }
  
         return buf.toString();
  
   }
  

  
   /**
  
      * Convert to a byte array.Note that the numbers are stored in big-endian order.
  
      *
  
      * @return the byte array
  
      */
  
   public byte[] toByteArray() {
  
         byte b[] = new byte;
  
         ByteBuffer bb = ByteBuffer.wrap(b);
  
         // by default BB is big endian like we need
  
         bb.putInt(_time);
  
         bb.putInt(_machine);
  
         bb.putInt(_inc);
  
         return b;
  
   }
  

  
   private int _compareUnsigned(int i, int j) {
  
         long li = 0xFFFFFFFFL;
  
         li = i & li;
  
         long lj = 0xFFFFFFFFL;
  
         lj = j & lj;
  
         long diff = li - lj;
  
         if (diff < Integer.MIN_VALUE)
  
             return Integer.MIN_VALUE;
  
         if (diff > Integer.MAX_VALUE)
  
             return Integer.MAX_VALUE;
  
         return (int) diff;
  
   }
  


  
   public int compareTo(ObjectId>  
         if (id == null)
  
             return -1;
  


  
         int x = _compareUnsigned(_time,>  
         if (x != 0)
  
             return x;
  


  
         x = _compareUnsigned(_machine,>  
         if (x != 0)
  
             return x;
  


  
         return _compareUnsigned(_inc,>  
   }
  

  
   /**
  
      * Gets the timestamp (number of seconds since the Unix epoch).
  
      *
  
      * @return the timestamp
  
      */
  
   public int getTimestamp() {
  
         return _time;
  
   }
  

  
   /**
  
      * Gets the timestamp as a {@code Date} instance.
  
      *
  
      * @return the Date
  
      */
  
   public Date getDate() {
  
         return new Date(_time * 1000L);
  
   }
  

  

  
   /**
  
      * Gets the current value of the auto-incrementing counter.
  
      *
  
      * @return the current counter value.
  
      */
  
   public static int getCurrentCounter() {
  
         return _nextInc.get();
  
   }
  

  

  
   static {
  

  
         try {
  
             // build a 2-byte machine piece based on NICs info
  
             int machinePiece;
  
             {
  
               try {
  
                     StringBuilder sb = new StringBuilder();
  
                     Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
  
                     while (e.hasMoreElements()) {
  
                         NetworkInterface ni = e.nextElement();
  
                         sb.append(ni.toString());
  
                     }
  
                     machinePiece = sb.toString().hashCode() << 16;
  
               } catch (Throwable e) {
  
                     // exception sometimes happens with IBM JVM, use random
  
                     LOGGER.log(Level.WARNING, e.getMessage(), e);
  
                     machinePiece = (new Random().nextInt()) << 16;
  
               }
  
               LOGGER.fine("machine piece post: " + Integer.toHexString(machinePiece));
  
             }
  


  
             // add a 2 byte process piece. It must represent not only the JVM but the>
  
             // Since static var belong to>  
             final int processPiece;
  
             {
  
               int processId = new Random().nextInt();
  
               try {
  
                     processId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode();
  
               } catch (Throwable t) {
  
               }
  


  
                >  
               int loaderId = loader != null ? System.identityHashCode(loader) : 0;
  

  
               StringBuilder sb = new StringBuilder();
  
               sb.append(Integer.toHexString(processId));
  
               sb.append(Integer.toHexString(loaderId));
  
               processPiece = sb.toString().hashCode() & 0xFFFF;
  
               LOGGER.fine("process piece: " + Integer.toHexString(processPiece));
  
             }
  

  
             _genmachine = machinePiece | processPiece;
  
             LOGGER.fine("machine : " + Integer.toHexString(_genmachine));
  
         } catch (Exception e) {
  
             throw new RuntimeException(e);
  
         }
  

  
   }
  

  
   @Override
  
   public boolean equals(Object o) {
  
         if (this == o) return true;
  
         if (o == null || getClass() != o.getClass()) return false;
  

  
         ObjectId that = (ObjectId) o;
  

  
         return Objects.equal(this.serialVersionUID, that.serialVersionUID) &&
  
               Objects.equal(this.LOGGER, that.LOGGER) &&
  
               Objects.equal(this._time, that._time) &&
  
               Objects.equal(this._machine, that._machine) &&
  
               Objects.equal(this._inc, that._inc) &&
  
               Objects.equal(this._new, that._new) &&
  
               Objects.equal(this._nextInc, that._nextInc) &&
  
               Objects.equal(this._genmachine, that._genmachine);
  
   }
  

  
   @Override
  
   public int hashCode() {
  
         return Objects.hashCode(serialVersionUID, LOGGER, _time, _machine, _inc, _new,
  
               _nextInc, _genmachine);
  
   }
  

  
   public static void main(String[] args) {
  
         System.out.println(new ObjectId().toHexString());
  
         System.out.println(new ObjectId().toHexString());
  
         System.out.println(new ObjectId().toHexString());
  
   }
  
}
页: [1]
查看完整版本: 生成类似于MongoDB产生的ObjectId