Java 包装类的二进制操作
Integer
位翻转
位翻转就是将二进制左边的位与右边的位进行互换,reverse 是按位进行互换, reverseBytes 是按 byte 进行互换。
public static int reverse(int i)public static int reverseBytes(int i)
来看个例子:
int a = 0x12345678;
System.out.println(Integer.toBinaryString(a));
// 0001 0010 0011 0100 0101 0110 0111 1000int r = Integer.reverse(a);
System.out.println(Integer.toBinaryString(r));
// 0001 1110 0110 1010 0010 1100 0100 1000int rb = Integer.reverseBytes(a);
System.out.println(Integer.toHexString(rb));
// 0111 1000 0101 0110 0011 0100 0001 0010
reverse 的实现:
public static int reverse(int i) {//HD, Figure 7-1i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;i = (i << 24) | ((i & 0xff00) << 8) |((i >>> 8) & 0xff00) | (i >>> 24);return i;
}
高效实现位翻转的基本思路是:首先交换相邻的单一位,然后以2位为一组,再交换相邻的位,接着是4位一组交换、然后是8位、16位,16位之后就完成了。
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; 是对单一位进行翻转。
x & 0x55555555 是取 x 的奇数位。
& 运算符的优先级比 | 运算符高。
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333; 是以两位为一组,对相邻位进行互换。
x & 0x33333333 是取 x 以两位为一组的奇数位。
…
reverse 代码为什么不能用更容易理解的方式写吗?比如,实现翻转,一种常见的思路是:第一个和最后一个交换,第二个和倒数第二个交换,直到中间两个交换完成。如果数据不是二进制位,这个思路是好的,但对于二进制位,这个思路的效率比较低。
CPU指令并不能高效地操作单个位,它操作的最小数据单位一般是32位(32位机器),另外,CPU可以高效地实现移位和逻辑运算,但实现加、减、乘、除运算则比较慢。reverse是在充分利用CPU的这些特性,并行高效地进行相邻位的交换,可以通过其他更容易理解的方式实现相同功能,但很难比这个代码更高效。
reverseBytes 的实现:
public static int reverseBytes(int i) {return ((i >>> 24))| ((i >> 8) & 0xFF00)| ((i << 8) & 0xFF0000)| ((i << 24));
}
循环移位
Integer 有两个静态方法可以进行循环移位。
public static int rotateLeft(int i, int distance)
public static int rotateRight(int i, int distance)
所谓循环移位,是相对于普通的移位而言的,普通移位,比如左移2位,原来的最高两位就没有了,右边会补0,而如果是循环左移两位,则原来的最高两位会移到最右边。
源码实现:
public static int rotateLeft(int i, int distance) {return (i << distance) | (i >>> -distance);
}public static int rotateRight(int i, int distance) {return (i >>> distance) | (i << -distance);
}
令人费解的是负数,如果 distance 是 8,那 i>>>-8 是什么意思呢?
实际的移位个数不是后面的直接数字,而是直接数字的最低 5 位的值,之所以这样,是因为 5 位最大表示 31,移位超过 31 位对 int 整数是无效的。
valueOf
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
IntegerCache表示Integer缓存,其中的cache变量是一个静态Integer数组,在静态初始化代码块中被初始化,默认情况下,保存了-128~127共256个整数对应的Integer对象。
在valueOf代码中,如果数值位于被缓存的范围,即默认-128~127,则直接从Integer-Cache中获取已预先创建的Integer对象,只有不在缓存范围时,才通过new创建对象。
通过共享常用对象,可以节省内存空间,由于Integer是不可变的,所以缓存的对象可以安全地被共享。
Character
Unicode
Unicode给世界上每个字符分配了一个编号,编号范围为0x000000~0x10FFFF。编号范围在0x0000~0xFFFF的字符为常用字符集,称BMP(Basic Multilingual Plane)字符。编号范围在0x10000~0x10FFFF的字符叫做增补字符(supplementary character)。
Unicode主要规定了编号,但没有规定如何把编号映射为二进制。UTF-16是一种编码方式,或者叫映射方式,它将编号映射为2个或4个字节,对BMP字符,它直接用两个字节表示;对于增补字符,使用4个字节表示,前两个字节叫高代理项(high surrogate),范围为0xD800~0xDBFF,后两个字节叫低代理项(low surrogate),范围为0xDC00~0xDFFF。UTF-16定义了一个公式,可以将编号与4字节表示进行相互转换。
Java内部采用UTF-16编码,char表示一个字符,但只能表示BMP中的字符,对于增补字符,需要使用两个char表示,一个表示高代理项,一个表示低代理项。
使用int可以表示任意一个Unicode字符,低21位表示Unicode编号,高11位设为0。整数编号在Unicode中一般称为代码点(code point),表示一个Unicode字符,与之相对,还有一个词代码单元(code unit)表示一个char。
参考:《Java 编程的逻辑》马俊昌
相关文章:
Java 包装类的二进制操作
Integer 位翻转 位翻转就是将二进制左边的位与右边的位进行互换,reverse 是按位进行互换, reverseBytes 是按 byte 进行互换。 public static int reverse(int i)public static int reverseBytes(int i)来看个例子: int a 0x12345678; S…...
CSS居中之 { left:50%; top:50%; transform:translate(-50%,-50%); }
CSS居中之 { left:50%; top:50%; transform:translate(-50%,-50%); } left:50%; top:50%; transform:translate(-50%,-50%); left:50%; top:50%; transform:translate(-50%,-50%);也可以写成: left:50%; top:50%; translate: -50% -50%; left:50%; top:50%; translate: -50%…...
AcWing 4868. 数字替换(DFS + 剪枝优化)
AcWing 4868. 数字替换(DFS 剪枝优化)一、问题二、思路三、代码一、问题 二、思路 题目中要求变换次数最小,其实第一印象应该是贪心,即我们每一次都去成各位中最大的那个数字。但是这个想法很容易推翻。因为你这次乘了一个最大的…...
【教学典型案例】01.redis只管存不管删除让失效时间删除的问题
目录一:背景介绍二:redis1)redis数据类型①String(字符串)②Hash(哈希)③List(列表)④Set(集合)2)缓存同步①设置有效期②同步双写③异步通知3&am…...
电话号码管理
电话号码管理 文章目录 电话号码管理综述链表结构initcreatedeleteallfreeANSI颜色转义颜色列表如下:字背景颜色范围:40--49 字颜色: 30--39输出特效格式控制:光标位置等的格式控制:Makefile顶层Makefilescripts Makefilesearch main init include display delete create all…...
Shell 教程
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 Ken Thompson 的…...
Shader 阴影
阴影生成原理 以平行光为例,把相机移动到光源位置,计算阴影映射纹理(shadowmap),这张shadowmap本质上是一张深度图,它记录了从该光源的位置出发、能看到的场景中距离它最近的表面位置(深度信息&…...
【冲刺蓝桥杯的最后30天】day2
大家好😃,我是想要慢慢变得优秀的向阳🌞同学👨💻,断更了整整一年,又开始恢复CSDN更新,从今天开始更新备战蓝桥30天系列,一共30天,如果对你有帮助或者正在备…...
docker系列1:docker安装
传送门 docker官网地址: Docker: Accelerated, Containerized Application Development 安装地址:Install Docker Engine docker hub地址 docker hub:Docker 安装步骤 前置条件 由于安装docker,需要根据操作系统版本选择…...
内核角度谈谈Linux进程和线程
目录前言内核对进程和线程的表示创建进程的过程创建线程的过程创建进程和线程的异同揭秘 do_fork 系统调用结论前言 昨天面试的时候,面试官问我了个平平淡淡的问题–>“聊聊Linux中进程和线程”; 相比大家不管是在考试还是面试中或多或少都遇到过这个问题&…...
【mmdeploy部署系列】使用Tensorrt加速部署mmpose人体姿态库
【mmdeploy部署系列】使用Tensorrt加速部署mmpose人体姿态库0.引言1.安装mmcv2.使用mmpose(1)安装mmpose(2)运行mmpose3.使用mmdeploy(1)安装ppl.cv(2)编译安装mmdeploy(…...
IDEA 每次新建工程都要重新配置 Maven 解决方案
IDEA 每次新建工程都要重新配置 Maven 解决方案 IDEA 每次新建工程都要重新配置 Maven,是一件相当浪费时间的事情。这是因为在创建一个项目后,在 File -> Settings -> Build,Execution,Deployment -> Build Tools -> Maven下配置了 Maven h…...
【C++修炼之路】25.哈希应用--布隆过滤器
每一个不曾起舞的日子都是对生命的辜负 布隆过滤器前言一.布隆过滤器提出二.布隆过滤器概念三. 布隆过滤器的操作3.1 布隆过滤器的插入3.2 布隆过滤器的查找3.3 布隆过滤器的删除四.布隆过滤器的代码4.1 HashFunc的仿函数参考4.2 BloomFilter.h五.布隆过滤器的优缺点六.布隆过滤…...
linux入门---权限
目录标题什么是权限人的分类为什么会有所属组查看文件属性文件的分类如何查看权限文件不同权限的表现rwx权限修改八进制权限修改umask有关内容文件中人的修改目录不同权限的表现rwx什么是权限 首先来看一个例子:比如说我没有爱奇艺的vip,那么我也就没有…...
Unity记录2.1-动作-多段跳、蹬墙跳、墙体滑落
文章首发及后续更新:https://mwhls.top/4450.html,无图/无目录/格式错误/更多相关请至首发页查看。 新的更新内容请到mwhls.top查看。 欢迎提出任何疑问及批评,非常感谢! 汇总:Unity 记录 摘要:实现跳跃、蹬…...
Spring Boot结合IDEA自带Maven插件快速切换profile | Spring Cloud 10
一、前言 IDEA是目前 Java 开发者中使用最多的开发工具,它有着简约的设计风格,强大的集成工具,便利的快捷键。 在项目项目整个开发运维周期中,我们的的项目往往需要根据不同的环境,使用不同的文件配置。 比如以下部…...
ES 7.7.0 数据迁移
本文使用 elasticdump 做数据迁移,支持在线和离线俩种方式,适用于数据量比较小的情况。 1、Node 安装 由于elasticdump 依赖于 node,首先需要安装下node。 1.1、 Linux 安装 $ wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linu…...
【玩转c++】vector讲解和模拟底层实现
本期主题:vector的讲解和模拟实现博客主页:小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐vector的介绍及使用1.1vector的介绍vector其实就是一个数组的模板 ,存放的数据可以改变而已…...
基本类型、包装类型、引用类型、String等作为实参传递后值会不会改变?
看了半天帖子,讲得乱七八糟,坑死了 [1] 先说结论 基本类型、包装类型、String类型作为参数传递之后,在方法里面修改他们的值,原值不会改变!引用类型不一定,要看是怎么修改它的。 [2] 为什么基本类型、包装类…...
Tomcat服务器配置以及问题解决方案
文章目录01 Tomcat简介02 Tomcat的安装03 Tomcat的使用启动Tomcat服务器 (解决一闪而过)测试 Tomcat 是否启动Tomcat 服务器的关闭04 Tomcat的配置配置端口控制台配置(乱码解决)部署工程到Tomcat中01 Tomcat简介 Tomcat是一款开源…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
dvwa11——XSS(Reflected)
LOW 分析源码:无过滤 和上一关一样,这一关在输入框内输入,成功回显 <script>alert(relee);</script> MEDIUM 分析源码,是把<script>替换成了空格,但没有禁用大写 改大写即可,注意函数…...
