java 二进制 位运算符

位运算符 & | ~ ^

& : 对两个二进制数按位做与运算,即 1 & 0 = 0; 1 & 1 = 1; 0 & 0 = 0;
| : 对两个二进制数按位做或运算,即 1 & 0 = 1; 1 & 1 = 1; 0 & 0 = 0;
~ : 对一个二进制数按位取反,即 ~1 = 0; ~0 = 1;
^ : 对两个二进制数按位做异或运算,即 1 ^ 1 = 0; 1 ^ 0 = 1, 0 ^ 0 = 0; 相同取0,不同取1

另:

1)
    十进制-1 的二进制表示,为书写简单假设 这里的10进制数字是16位的int类型,以下十进制用D()表示
    D(1) = 0000 0000 0000 0001
    D(-1) 原码 = 1000 0000 0000 0001
    D(-1) 补码 = 1111 1111 1111 1111 原码的基础上除符号位以外按位取反后+1
2) 用R表示任意数
    2.1) 0 & R = 0; 1 & R = R; R & R = R;
    2.2) 1 | R = 1; 0 | R = R; R | R = R;
    2.3) 1 ^ R = ~R; 0 ^ R = R; R ^ R = 0;

实例
商城在对商品做分析的时候,需要根据用户行为对商品打一些标记,有许多标记就是‘是/否’的一种逻辑,
假设需要打标记:1 是否促销  2 正品 3 参加双十一 4 参加双十二 等等
提供一个比较好玩的方法
既然这些标记都是‘是否’的取值逻辑,即是否打这个标记,那么我们就可以用二进制来表示。
设定一个int字段,这个字段值的特定位表示特定的tag,取值1表示打标记,取值0表示不打标记

package Binary;

public class BinaryTag {
    static class Goods {
        private String name;
        private int tag;
        
        public Goods() {}
        
        public Goods(String name, int tag) {
            this.name = name;
            this.tag = tag;
        }
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getTag() {
            return tag;
        }
        public void setTag(int tag) {
            this.tag = tag;
        }
    }
    class Tag {
        public final static int None = 0; // 没有标记
        public final static int All = -1; // 全部标记 1111 …… 1111
        public final static int Promotion = 1; // 促销标记 0001
        public final static int Genuine = 2; // 正品标记 0010
        public final static int Double11 = 4; // 双十一 0100
        public final static int Double12 = 8; // 双十二 1000
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        Goods nike = new Goods("Nike", Tag.None);
        
        System.out.print("标为正品;");
        mark(nike, Tag.Genuine);
        System.out.print("参加促销;");
        mark(nike, Tag.Promotion);
        System.out.print("参加双十一;");
        mark(nike, Tag.Double11);
        System.out.println("不参加双十二;");
        clearMark(nike, Tag.Double12);
        descGoods(nike);
        
        System.out.println("不促销了,也不参加双十一了;");
        clearMark(nike, Tag.Promotion + Tag.Double11);
        descGoods(nike);
        
        System.out.println("反转双十一和双十二的标记;");
        reverseMark(nike, Tag.Double11 + Tag.Double12);
        descGoods(nike);
        
        System.out.println("反转双十一和双十二的标记;");
        reverseMark(nike, Tag.Double11 + Tag.Double12);
        descGoods(nike);
        
        System.out.println("添加全部标记;");
        markAll(nike);
        descGoods(nike);
        
        System.out.println("清除所有标记;");
        clearAllMark(nike);
        descGoods(nike);
    }
    /**
     * 添加某种标记
     * @param goods
     * @param tag
     */
    public static void mark(Goods goods, int tag) {
        int oldTag = goods.getTag();
        // 将tag位 置为1 引用 [2.2) 1 | R = 1; 0 | R = R; R | R = R;]
        int newTag = (oldTag | tag);
        goods.setTag(newTag);
    }
    /**
     * 打上所有的标记
     * @param goods
     */
    public static void markAll(Goods goods) {
        goods.setTag(Tag.All);
    }
    /**
     * 消除商品tag
     * @param goods
     * @param tag
     */
    public static void clearMark(Goods goods, int tag) {
        int oldTag = goods.getTag();
        int newTag = (oldTag & (~tag));
        goods.setTag(newTag);
    }
    /**
     * 消除全部标记
     * @param goods
     */
    public static void clearAllMark(Goods goods) {
        goods.setTag(Tag.None);
    }
    /**
     * 对指定标记进行反转
     * @param goods
     * @param tag
     */
    public static void reverseMark(Goods goods,int tag) {
        int oldTag = goods.getTag();
        int newTag = (oldTag ^ tag);
        goods.setTag(newTag);
    }
    /**
     * 是否打了这种标记
     * @param goods
     * @param tag
     * @return
     */
    public static boolean isTaged(Goods goods, int tag) {
        int oldTag = goods.getTag();
        return tag == (oldTag & tag);
    }
    
    public static void descGoods(Goods goods) {
        System.out.print(goods.getName()+":");
        System.out.print((isTaged(goods, Tag.Promotion)?"":"不") + "参加促销;");
        System.out.print((isTaged(goods, Tag.Genuine)?"":"不") + "是正品;");
        System.out.print((isTaged(goods, Tag.Double11)?"":"不") + "参加双十一;");
        System.out.print((isTaged(goods, Tag.Double12)?"":"不") + "参加双十二;");
        System.out.println("\n");
    }
}

 Console:

标为正品;参加促销;参加双十一;不参加双十二;
Nike:参加促销;是正品;参加双十一;不参加双十二;

不促销了,也不参加双十一了;
Nike:不参加促销;是正品;不参加双十一;不参加双十二;

反转双十一和双十二的标记;
Nike:不参加促销;是正品;参加双十一;参加双十二;

反转双十一和双十二的标记;
Nike:不参加促销;是正品;不参加双十一;不参加双十二;

添加全部标记;
Nike:参加促销;是正品;参加双十一;参加双十二;

清除所有标记;
Nike:不参加促销;不是正品;不参加双十一;不参加双十二;

 

posted on 2015-04-16 19:05  Erbin  阅读(544)  评论(0编辑  收藏  举报

导航