位运算

一.String

String a="abc";    //会在常量池中开辟一块空间,保存"abc"
String b="new String("abc");

  01.常量池没有abc,首先会在常量池开辟一块空间,保存"abc"。  

  02.再去堆中开辟一块空间,保存"abc"。

  03.b指向堆中abc   

a==b   false
String c=new String("abc");
b==c   false
intern();从常量池中取地址
a==b.intern()==c.intern()    true

***************************************************************************************************************************************

String a="abc";
String b="a";
String c="bc";
a,b,c三者都是变量!!!!

a==(b+c) false

String a="abc";
final String b="a";
final String c="bc";
b,c两者都是常量!!!! 不允许被改变

a==(b+c) true

二.集合 Collection

  存储一组相同数据类型的集合====》数组!  Array  Arrays

  List   存储的是不唯一,无序的数据

  HashSet的底层实现其实就是HashMap
    

TreeSet 有序的数据

    Set set=new HashSet();

    set.add("abc");
    set.add(new String("abc"));
    set.add(new String("abc"));
    System.out.println(set.size());

步骤:
    01.ctrl+选中add 进入了 set的底层
    02.再次点击add 进去hashSet的add()
  map.put(k,v)
    03.再次点击put()
  public V put(K key, V value) {
  return putVal(hash(key), key, value, false, true);
  }
  不同的字符串,有可能hashcode值一致
  相同的字符串,hashcode值绝对一致
  以空间换时间 (猪圈)

    04.再次点击putVal
    05.观察代码 发现分为3个步骤
  p.hash == hash &&
  ((k = p.key) == key || (key != null && key.equals(k)))
    001.比较hash值 (简单int,如果hashcode不一致,不需要再比较了)
    002.比较内存地址
    003.比较具体的内容

二.Map
  HashMap hash+链表(数据结构)
  负载因子 0.75
  如果超过了负载因子,则会创建原来bucket数组的两倍数量
  线程不安全

  HashTable

3.位运算
         int newCapacity = 10 + (10 >> 1);
10000001  左为高  右为低
    int  4个字节byte  32bit位
数字1 转换成 2 进制
00000000 00000000 00000000 00000001   32位

521    10进制

1*10的0次方 =1
2*10的1次方 =20
5*10的2次方 =500

00000000 00000000 00000000 00000101   5对应的2进制
1*2的0次方 =1
0*2的1次方 =0
1*2的2次方 =4

1G=1024MB 计算机在运行时
1G=1000MB




01010101    2进制
原码   ===》我们看到的    3
反码
补码   ===》真正运行的

01.正数的原码,反码,补码都一致
02.java中所有的数字都是有符号的  符号位 正数0  负数1
03.负数的反码=符号位不变+其他位取反(1变0 0变1)
04.负数的补码=反码+1

例子: 1-2 
 先把1转换成2进制
 0 0 0 0 0 0 0 1-2转换成2进制
 1 0 0 0 0 0 1 0    -2的源码
 1 1 1 1 1 1 0 1    -2的反码
 1 1 1 1 1 1 1 0    -2的补码

 
   0 0 0 0 0 0 0 1   1的补码
+  1 1 1 1 1 1 1 0
============================ 
   1 1 1 1 1 1 1 1    结果的补码
   1 1 1 1 1 1 1 0    结果的反码 
   1 0 0 0 0 0 0 1    结果的原码   -1       


 例子:5-7
     先把5转换成二进制
     0 0 0 0 0 1 0 1

     再把-7转换成二进制
     1 0 0 0 0 1 1 1     -7的源码
     1 1 1 1 1 0 0 0     -7的反码
     1 1 1 1 1 0 0 1     -7的补码


    0 0 0 0 0 1 0 1
   +1 1 1 1 1 0 0 1
======================================
    1 1    1 1    1 1 1 0     结果的补码
    1 1    1 1    1 1 0 1     结果的反码
    1 0 0 0 0 0 1 0     结果的源码
    二进制转换为十进制
    结果为:-2


例子: 4-3    

 先把4转换成2进制
 0 0 0 0 0 1 0 0-3转换成2进制
 1 0 0 0 0 0 1 1   -3的源码
 1 1 1 1 1 1 0 0   -3的反码
 1 1 1 1 1 1 0 1   -3的补码
+0 0 0 0 0 1 0 0
==========================
 0 0 0 0 0 0 0 1  结果的补码


例子:9-4

先把9转换为二进制
0 0 0 0 1 0 0 1

再把-4转换为二进制
1 0 0 0 0 1 0 0     -4的源码
1 1 1 1 1 0 1 1     -4的反码
1 1 1 1 1 1 0 0     -4的补码

 0 0 0 0 1 0 0 1
+1 1 1 1 1 1 0 0
=================================
 0 0 0 0 0 1 0 1     结果的补码(正数补码,反码,源码相同) 5
 


算术右移
int newCapacity = 10 + (10 >> 1);

先算出10的2进制
0 0 0 0 1 0 1 0
  0 0 0 0 1 0 1 0    符号位不变,低位溢出删除,高位补零!
==========================================
0 0 0 0 0 1 0 1

算术右移
int newCapacity = 9 + (9 >> 2);
0 0 0 0 1 0 0 1
    0 0 0 0 1 0 0 1
===================================
0 0 0 0 0 0 1 0     结果为  2    



算术左移
10 << 1

   先算出10的2进制
   0 0 0 0 1 0 1 0
 0 0 0 0 1 0 1 0     符号位不变,高位溢出删除,低位补零!
 ==============================
   0 0 0 1 0 1 0 0    20


算术左移
16 << 4

         0 0 0 0 1 0 1 1
   0 0 0 0 1 0 1 1
===============================
         0 1 0 1 1 0 0 0

    64+16+8=88

怎么以最快的速度从2 变成 8

    先算出2的2进制
    0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 0     2<<2
============================
    0 0 0 0 1 0 0 0    8


逻辑右移:不管符号位!低位溢出删除,高位补零!

10>>>2
    先算出10的2进制
    0 0 0 0 1 0 1 0
        0 0 0 0 1 0 1 0
=======================
    0 0 0 0 0 0 1 0


-1
  1 0 0 0 0 0 0 1  原码
  1 1 1 1 1 1 1 0  反码
  1 1 1 1 1 1 1 1  补码   >>>1
    1 1 1 1 1 1 1 1
========================
  0 1 1 1 1 1 1 1 




&& || !   逻辑与或非   短路与或非  返回的都是boolean类型的值

位运算:  

按位与 &   两位都为1,结果为1

例1:
  3&4
  0 0 0 0 0 0 1 1
& 0 0 0 0 0 1 0 0
===========================
  0 0 0 0 0 0 0 0

例2:
    
    6&3
    0 0 0 0 0 1 1 0
   &0 0 0 0 0 0 1 1
==============================
    0 0 0 0 0 0 1 0
    结果为2
   
按位或 |   两位有一位为1,结果为1

例1:
  3|2
  0 0 0 0 0 0 1 1
| 0 0 0 0 0 0 1 0
===========================
  0 0 0 0 0 0 1 1 

例2:
    8|8
  0 0 0 0 1 0 0 0 
 |0 0 0 0 1 0 0 0 
 =======================
  0 0 0 0 1 0 0 0
    结果为8


按位异或 ^   必须是一位是0,一位是1,结果才为1

例1:
  3^4
  0 0 0 0 0 0 1 1
^ 0 0 0 0 0 1 0 0
===========================
  0 0 0 0 0 1 1 1 

例2:
   9^7
   0 0 0 0 1 0 0 1
  ^0 0 0 0 0 1 1 1
  ==========================
   0 0 0 0 1 1 1 0

   结果为14


按位取反 ~  : 就是数值+1之后取相反的值

 ~3

~  0 0 0 0 0 0 1 1
=========================
   1 1 1 1 1 1 0 0    负数
   1 0 0 0 0 0 1 1    反码
   1 0 0 0 0 1 0 0
原文地址:https://www.cnblogs.com/wang2386033566/p/9290858.html