1. 程式人生 > >Guava處理原生型別的資料

Guava處理原生型別的資料

概述

Java的原生型別就是指基本型別:byte、short、int、long、float、double、char和boolean。

  • 基本型別byte: 8位 -128~127

  • 基本型別char char 是字元資料型別 ,是無符號型的,佔2位元組(Unicode碼),大小範圍 是0—65535;char是一個16位二進位制的Unicode字元,JAVA用char來表示一個字元 。Java是用unicode來表示字元,”中”這個中文字元的unicode就是2個位元組。通常gbk/gb2312是2個位元組,utf-8是3個位元組。如果不指定encoding則取系統預設的encoding。

  • 基本型別:short 二進位制位數:16
    包裝類:java.lang.Short
    最小值:Short.MIN_VALUE=-32768 (-2的15此方)
    最大值:Short.MAX_VALUE=32767 (2的15次方-1)

  • 基本型別:int 二進位制位數:32
    包裝類:java.lang.Integer
    最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
    最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)

  • 基本型別:long 二進位制位數:64
    包裝類:java.lang.Long
    最小值:Long.MIN_VALUE=-9223372036854775808 (-2的63次方)
    最大值:Long.MAX_VALUE=9223372036854775807 (2的63次方-1)

  • 基本型別:float 二進位制位數:32
    包裝類:java.lang.Float

  • 基本型別:double 二進位制位數:64
    包裝類:java.lang.Double

  • float的小數點後6位,double的小數點後16位。

  • 建議:在從Guava查詢原生型別方法之前,可以先查查Arrays類,或者對應的基礎型別包裝類,如Integer,Float。Integer是一個類,是int的擴充套件,定義了很多的轉換方法類似的還有float,Float;doubleDouble;String等,其中String較為特殊,基本型別和複雜類似關鍵字相同。

Guava原聲型別的支援

  • 意義:原生型別不能當作物件或泛型的型別引數使用,這意味著許多通用方法都不能應用於它們。Guava提供了若干通用工具,包括原生型別陣列與集合API的互動,原生型別和位元組陣列的相互轉換,以及對某些原生型別的無符號形式的支援。

支援的所有的:

原生型別 Guava工具類(都在com.google.common.primitives包)
byte Bytes, SignedBytes, UnsignedBytes
short Shorts
int Ints, UnsignedInteger, UnsignedInts
long Longs, UnsignedLong, UnsignedLongs
float Floats
double Doubles
char Chars
boolean Booleans

Bytes工具類沒有定義任何區分有符號和無符號位元組的方法,而是把它們都放到了SignedBytes和UnsignedBytes工具類中,因為位元組型別的符號性比起其它型別要略微含糊一些。

int和long的無符號形式方法在UnsignedInts和UnsignedLongs類中,但由於這兩個型別的大多數用法都是有符號的,Ints和Longs類按照有符號形式處理方法的輸入引數。

此外,Guava為int和long的無符號形式提供了包裝類,即UnsignedInteger和UnsignedLong,以幫助你使用型別系統,以極小的效能消耗對有符號和無符號值進行強制轉換。

在本章下面描述的方法簽名中,我們用Wrapper表示JDK包裝類,prim表示原生型別。(Prims表示相應的Guava工具類。)

Bytes

把陣列轉為相應包裝類的List

  1. List asList(prim… backingArray)
  2. Arrays.asList類似這個
 //這個是包裝陣列,不然會報錯的 JDK的
 List<Byte> listByte = Arrays.asList(new Byte[]{1,2,3});

 //這個是原生的資料沒得事 Guava的
 List<Byte> listbyte = Bytes.asList(new byte[]{1,2,3});

JDK的實現:使用了ArrayList

   public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

Guava的實現,自己繼承抽象List,新的List的實現

 public static List<Byte> asList(byte... backingArray) {
    if (backingArray.length == 0) {
      return Collections.emptyList();
    }
    return new ByteArrayAsList(backingArray);
  }

這裡自己實現的ByteArrayAsList和Collections.emptyList一樣的,都是重寫了一個immutalbe-list
EmptyList

 public static final List EMPTY_LIST = new EmptyList<>();
 public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
 }
 // immtable 的emptyList 很多的額許可權都沒得哈哈
 private static class EmptyList<E>
        extends AbstractList<E>
        implements RandomAccess, Serializable {

        public Iterator<E> iterator() {
            return emptyIterator();
        }
        public ListIterator<E> listIterator() {
            return emptyListIterator();
        }

        public int size() {return 0;}
        public boolean isEmpty() {return true;}

        public boolean contains(Object obj) {return false;}
        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }

        public Object[] toArray() { return new Object[0]; }

        public <T> T[] toArray(T[] a) {
            if (a.length > 0)
                a[0] = null;
            return a;
        }

        public E get(int index) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }

        public boolean equals(Object o) {
            return (o instanceof List) && ((List<?>)o).isEmpty();
        }

        public int hashCode() { return 1; }
    }

Guava Bytes中的內部類的處理,儲存的是原生的byte,sublist也是使用同一個list,沒有進行資料的複製,但是不是執行緒安全的類!

private static class ByteArrayAsList extends AbstractList<Byte>
      implements RandomAccess, Serializable {
    final byte[] array;
    final int start;
    final int end;

    ByteArrayAsList(byte[] array) {
      this(array, 0, array.length);
    }

    ByteArrayAsList(byte[] array, int start, int end) {
      this.array = array;
      this.start = start;
      this.end = end;
    }

    @Override
    public int size() {
      return end - start;
    }

    @Override
    public boolean isEmpty() {
      return false;
    }
    //只有Get的使用才是轉換為Byte封裝類
    @Override
    public Byte get(int index) {
      checkElementIndex(index, size());
      return array[start + index];
    }

    @Override
    public boolean contains(Object target) {
      // Overridden to prevent a ton of boxing
      return (target instanceof Byte) 
      && 
      Bytes.indexOf(array, (Byte) target, start, end) != -1;
    }

    @Override
    public int indexOf(Object target) {
      // Overridden to prevent a ton of boxing
      if (target instanceof Byte) {
        int i = Bytes.indexOf(array, (Byte) target, start, end);
        if (i >= 0) {
          return i - start;
        }
      }
      return -1;
    }

    @Override
    public int lastIndexOf(Object target) {
      // Overridden to prevent a ton of boxing
      if (target instanceof Byte) {
        int i = Bytes.lastIndexOf(array, (Byte) target, start, end);
        if (i >= 0) {
          return i - start;
        }
      }
      return -1;
    }
    @Override
    public Byte set(int index, Byte element) {
      checkElementIndex(index, size());
      byte oldValue = array[start + index];
      // checkNotNull for GWT (do not optimize)
      array[start + index] = checkNotNull(element);
      return oldValue;
    }

    @Override
    public List<Byte> subList(int fromIndex, int toIndex) {
      int size = size();
      checkPositionIndexes(fromIndex, toIndex, size);
      if (fromIndex == toIndex) {
        return Collections.emptyList();
      }//使用同一個陣列
      return new ByteArrayAsList(array, start + fromIndex, start + toIndex);
    }
    //使用JDK的
    byte[] toByteArray() {
      return Arrays.copyOfRange(array, start, end);
    }
    private static final long serialVersionUID = 0;
  }

Guava Bytes中方法

  • 查詢 int indexOf(prim[] array, prim target)
  • 給定值在陣列中首次出現處的索引,若不包含此值返回-1
  • 類似 List.indexOf
public static int indexOf(byte[] array, byte target) {
    return indexOf(array, target, 0, array.length);
  }
private static int indexOf(byte[] array, byte target, int start, int end) {
    for (int i = start; i < end; i++) {
      if (array[i] == target) {
        return i;
      }
    }
    return -1;
}
private static int lastIndexOf(byte[] array, byte target, int start, int end) {
    for (int i = end - 1; i >= start; i--) {
      if (array[i] == target) {
        return i;
      }
    }
    return -1;
  }
  • 連線,這種操作,都是基於原生的型別進行處理的!
  • prim[] concat(prim[]… arrays)
  • 串聯多個原生型別陣列
  • 類似方法:Iterables.concat
public static byte[] concat(byte[]... arrays) {
    int length = 0;
    for (byte[] array : arrays) {
      length += array.length;
    }
    byte[] result = new byte[length];
    int pos = 0;
    for (byte[] array : arrays) {
      System.arraycopy(array, 0, result, pos, array.length);
      pos += array.length;
    }
    return result;
}

把集合拷貝為陣列,和collection.toArray()一樣執行緒安全

  1. prim[] toArray(Collection collection)
  2. Collection.toArray() 類似這個方法

JDK中集合toArray

List<Integer> list =Arrays.asList(1,2,3,45);
Integer[] a = (Integer[]) list.toArray();

//這裡是Object物件,轉換為其他的還要報錯。
//只能和當前的陣列型別相關的包裝類
public Object[] toArray() {
  return Arrays.copyOf(elementData, size);
}
//而且這裡只能轉換為包裝類

看看Bytes中的實現,將Collection轉換為基本型別的byte[]

  List<Integer> list =Arrays.asList(1,2,3,256);
    byte[] changByBytes = Bytes.toArray(list);
    for(int i=0;i < changByBytes.length;i++){
        System.out.println("i:"+changByBytes[i]);
  }
i:1
i:2
i:3
i:0

怎麼樣不錯吧,哈哈,速度可以的~
先看看JDK Number介面,各種包裝類都繼承這個玩意

用於在原始型別之間轉換。因此,轉換可能丟失有關數值的整體大小的資訊,失去精度,甚至可能返回一個不同的標誌的結果。

public abstract class Number implements java.io.Serializable {

    public abstract int intValue();

    public abstract long longValue();

    public abstract float floatValue();

    public abstract double doubleValue();

    public byte byteValue() {
        return (byte)intValue();
    }
    public short shortValue() {
        return (short)intValue();
    }
}

這裡還是使用collection.toArray,然後轉換為byte,這個可能會失去精度!優勢在哪裡,返回原生的資料型別。

public static byte[] toArray(Collection< ? extends Number> collection) {
    if (collection instanceof ByteArrayAsList) {
      return ((ByteArrayAsList) collection).toByteArray();
    }

    Object[] boxedArray = collection.toArray();
    int len = boxedArray.length;
    byte[] array = new byte[len];
    for (int i = 0; i < len; i++) {
      // checkNotNull for GWT (do not optimize)
      array[i] = ((Number) checkNotNull(boxedArray[i])).byteValue();
    }
    return array;
  }

陣列中最小大的值

  • prim min(prim… array) prim max(prim… array)
  • Collections.max 類似這個
  • 不過這個是對於原生的陣列
    Ints中的哦!
public static int min(int... array) {
    checkArgument(array.length > 0);
    int min = array[0];
    for (int i = 1; i < array.length; i++) {
      if (array[i] < min) {
        min = array[i];
      }
    }
    return min;
  }

把陣列用給定分隔符連線為字串

  • String join(String separator, prim… array)
  • Joiner.on(separator).join 類似這個(不過這個要強大一點)
    Ints中的哦!
public static String join(String separator, int... array) {
    checkNotNull(separator);
    if (array.length == 0) {
      return "";
    }

    // For pre-sizing a builder, just get the right order of magnitude
    StringBuilder builder = new StringBuilder(array.length * 5);
    builder.append(array[0]);
    for (int i = 1; i < array.length; i++) {
      builder.append(separator).append(array[i]);
    }
    return builder.toString();
  }

把int轉換為byte陣列

public static byte[] toByteArray(int value) {
    return new byte[] {
      (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
    };
  }

把byte轉換為int

public static int fromByteArray(byte[] bytes) {
    checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES);
    return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
  }
public static int fromBytes(byte b1, byte b2, byte b3, byte b4) {
    return b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
  }

相關推薦

Guava處理原生型別資料

概述 Java的原生型別就是指基本型別:byte、short、int、long、float、double、char和boolean。 基本型別byte: 8位 -128~127 基本型別char char 是字元資料型別 ,是無符號型的,佔2位元組(Uni

前端模板jinja2處理列舉型別資料

前提: class Orderstate(enum.Enum): UNSOLVED = 0 # 未解決 HANDING = 1 # 處理中 SOLVED = 2 # 已經解決 BACK = 4 # 待定 class Workorder(db.Model

[Google Guava] 7-原生型別

原文連結 譯文連結 譯者:沈義揚,校對:丁一 概述 Java的原生型別就是指基本型別:byte、short、int、long、float、double、char和boolean。 在從Guava查詢原生型別方法之前,可以先查查Arrays類,或者對應的基礎型別包裝類,如Integer。 原生型

java處理json型別資料--阿里巴巴fastjson api常用方法實戰

fastjson介紹 最近工作上經常需要解析json型別資料以及java物件到json型別的互轉,特地研究了下阿里巴巴的fastjson,這個是國內用的 比較多的json轉換api,還有其他的入jackson,谷歌的Gson,後續我再介紹。 廢話少說,上例子。 使用方式

jsoncpp 不能處理long型別資料

jsoncpp,是一個c++的解析和生成json的開源工具。如果你的c++程式需要解析或生成json,它會使這個過程變得很簡單! 但是,今天在用jsoncpp進行生成json的時候報了錯誤,很顯然這不是我程式的問題。 Test.cpp: In function ‘std:

spring,hibernate處理Lob型別資料

Lob代表大物件資料,包括BLOB和CLOB兩種型別資料,前者用於儲存大塊的二進位制資料,如圖片和視訊資料等,而後者用於儲存長文字資料,如論壇帖子內容,產品詳細描述等。在不同的資料庫中,大物件對應的欄位型別往往不一樣,如oracle對應的是BLOB/CLOB;Mysql對應

如何處理BLOB型別資料之三:使用Servlet在頁面上顯示BLOB中的圖片

實驗環境:JDeveloper 11.1.2.0.0。接上一個實驗《如何處理BLOB型別資料之二:下載BLOB內容並儲存到檔案中》。我的設計思想:這其實是一個動態顯示圖片的問題,類似於很多網站上登入時要求輸入的圖片認證碼。一開始,根據前面的思路,我打算繼續使用ADF BC的

字串型別資料處理的一個簡單小方法

今天開始試著去做kaggle上的入門競賽House Prices,因為資料集有81列,即81個特徵,一列一列處理資料很頭疼,於是想自己寫幾個方法 先寫了一個簡單的,可以自動把字串型別的特徵按數字順序編碼,如果資料中含有NAN或空元素就填入0,方便之後的處理 寫出來之後發現執行效率很低,處理一

非同步處理XML非同步資料——以原生的JavaScript與jQuery中的$.ajax()為例

此文件解決以下問題: 一、原生的JavaScript從伺服器端輸出XML格式資料 1.XMLHttpRequest物件的運用   XMLHttpRequest物件的open()方法   XMLHttpRequest物件的send()方法   XMLHttpRequest物件的onreadystate

jdbc 如何處理Blob型別欄位的資料

jdbc處理大物件Blob  在貼程式碼之前先講一下什麼是LOB大物件資料  LOB 大物件 是用來儲存大量的二進位制和文字資料的一種資料型別(一個LOB欄位可儲存多達 4GB的資料)   LOB分類兩種型別: (1)內部, (2)外部

python2處理xlsx混合型別資料

概述 最近在處理一些資料,將之從xlsx中插入到資料庫中,其中有些資料是數字,有些是中英文混合,有些是空值,其中還有特殊的日期格式,即讀取出來是數字,但在Excel中顯示的是某年某月某日,這個只能手動來

redis對String型別資料處理

package com.xwolf.java.redis; import org.junit.Before; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedi

double型別資料做加和操作時會丟失精度問題處理

double型別的資料做加和操作 時會丟失精度,如下操作結果為:         int a = 3;         double b = 0.03;         double c = 0.03;         double d = a + b + c;      

前臺js傳入json或map型別資料給後臺及後臺接收處理操作

5.java後端使用request拿到json資料String ds = request.getParameter("postData");JSONArray json=JSONArray.fromObject(ds); //使用net.sf.json.JSONObject物件來解析jsonJSONObjec

mybatis 處理陣列型別及使用Json格式儲存資料 JsonTypeHandler and ArrayTypeHandler

mybatis 比 ibatis 改進了很多,特別是支援了註解,支援了plugin inteceptor,也給開發者帶來了更多的靈活性,相比其他ORM,我還是挺喜歡mybatis的。 閒言碎語不要講,今天研究了下mybatis的typeHandler: 先看這樣一張

pandas處理時間和日期型別資料

匯入一個時間相關的資料集 import numpy as np import pandas as pd ## importing a dataset url="http://mlr.cs.umass.edu/ml/machine-learning-dat

java 直接返回Date型別資料給前端,前端的處理方法

// 前端獲取到資料格式是: // "drvierDate":{"date":9,"day":6,"hours":16,"minutes":30,"month":7,"nanos":0,"seconds":0,"time":1407573000000,"timezoneOf

前後臺時間型別資料處理

前臺傳遞給後臺 在web專案的controller中使用如下程式碼 @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dat

json Date型別資料處理

我們經常使用 JSONArray array=JSONArray.fromObject() 將物件集合  List  轉換成jsp所需的   JSONArray   形式 但是當處理到的  List  中包含  Date  型別的資料時,會出現錯誤。 此時,我們應該怎

JavaScriptSerializer序列化成Json時DateTime型別資料處理

JavaScriptSerializer在序列化時會將DateTime的資料序列化成類似\/Date(626543800000)\/這樣的值,找了很多方法都不如意,最後在一個部落格找到了完美的解決方法,地址:http://blog.calyptus.eu/seb/20