kotlin位操做和位運算

1、位操做:java

shl(bits) – 左移位 (Java’s <<)
shr(bits) – 右移位 (Java’s >>)
ushr(bits) – 無符號右移位 (Java’s >>>)
and(bits) – 與  &
or(bits) – 或   ||
xor(bits) – 異或
inv() – 反向





數組

val a = 5
val b = a shl 2 //左移2位,5*2*2=20
println(b)  //20

2、位運算符:code

運算符 表示含義
and(bits) 按位與
or(bits) 按位或
inv(bits) 按位非
xor(bits) 按位異或
shl(bits) 左移運算符
shr(bits) 右移運算符
ushr(bits) 無符號右移運算符

注意:Kotlin的位運算符只能對Int和Long兩種數據類型起做用。內存

(src[i].toInt().ushr(4)) and 0x0F)

3、位操做和位運算實例ci

經過位運算來保證頭尾不超過數組範圍,經過位操做來擴容(數組長度保持爲2的整數倍,方便進行位運算)element

//如ArrayDeque經過位與運算(等價於java中的'&'),保證頭尾不超過數組邊界
class SimpleIntArrayDeque {
    private var elements: Array<Int?> = arrayOfNulls(16) //擴容數組
    private var head: Int = 0 //頭
    private var tail: Int = elements.size //尾,tail-1是當前最後一位數據
 
    fun addFirst(value: Int) {
        if (value == null)
            throw NullPointerException()
        //當head-1爲-1時,其實是11111111&00111111,結果是00111111,也就是物理數組的尾部15;
        head = (head - 1) and (elements.size - 1)
        elements[head] = value
        if (head == tail)
            doubleCapacity()
    }
 
    fun addLast(value: Int) {
        if (value == null)
            throw NullPointerException()
        elements[tail] = value
        //當tail+1爲16時,其實是01000000&00111111,結果是00000000,也就是物理數組的頭部0;
        tail = (tail + 1) and (elements.size - 1)
        if (tail == head)
            doubleCapacity()
    }
    
    fun pollFirst(): Int? {
        val h = head
        val result = elements[h]
        if (result != null) {
            elements[h] = null
            head = (h + 1) and (elements.size - 1)
        }
        return result
    }
    
    fun pollLast(): Int? {
        val t = (tail - 1) and (elements.size - 1)
        val result = elements[t]
        if (result != null) {
            elements[t] = null
            tail = t
        }
        return result
    }
 
    //擴容:插入數據前,判斷插入後將頭尾相等(即插入後數組將填滿),則當即擴容
    private fun doubleCapacity() {
        val p = head
        val n = elements.size
        val r = n - p
        var newCapacity = n shl 1  //擴容2倍
        if (newCapacity < 0)
            throw IllegalArgumentException("Sorry, deque too big")
        var newElements: Array<Int?> = arrayOfNulls(newCapacity)
        //從頭部開始拷貝,拷貝頭部之後的全部內容,並把頭部位置重置爲0
        System.arraycopy(elements, p, newElements, 0, r)
        /**
         * 從0開始拷貝,拷貝頭部以前的內容,並把拷貝內容接上剛纔拷貝的位置,
         * 使得原來的數組放到新數組的前半部分
         */
        System.arraycopy(elements, 0, newElements, r, p)
        //釋放舊的數組內存
        Arrays.fill(elements, null)
        elements = newElements
        head = 0
        tail = n
    }
    
    fun size(): Int {  //插入前判斷,若插入後佔滿則當即擴容,所以size不會大於數組長度減一
        return (tail - head) and (elements.size - 1)
    }
    
    fun isEmpty(): Boolean {
        return head == tail
    }
 
    fun peekFirst(): Int? {
        return elements[head]
    }
 
    fun peekLast(): Int? {
        return elements[(tail -1) and (elements.size - 1)]
    }
}
相關文章
相關標籤/搜索