首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java String类源码解析

String直接继承Object 含有一个char[] value,还有一个int hash默认值为0 new String()的构造产生的是一个值为””的字符数组 String(char value[], int offset, int count)当count=0且offset<=value.length时构造一个值为””的字符串。offset>0且offset+count<=value.length时复制该部分子串。其余情况都会抛错。 字符数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。而length返回的是UTF-16下的代码单元的数量,而codePointCount返回的是代码点的数量。对于大部分人工输入的字符,这两者是相等的,会出现length比codePointCount长的通常是某些数学或者机器符号,需要两个代码单元来表示一个代码点。 对于返回char[]的方法,底层调用的是System.arraycopy方法,这也是高效的数组拷贝函数。 getBytes方法会调用StringCoding.encode返回序列化后的byte[] 关于String a == String b的判断,是指a和b指向内存中的同一个对象,凡是new String初始化的对象,都不会产生a==b的情况,因为他会新开辟一个对象空间,然后复制value的值,仅当b=a初始化时a==b成立。 public static void main(String args[]) { String a, b; a = "123"; b = "123"; System.out.println(a==b);//true a = "123"; b = new String("123"); System.out.println(a==b);//false a = new String("123"); b = new String("123"); System.out.println(a==b);//false a = "123"; b = new String(a); System.out.println(a==b);//false a = new String("123"); b = a; System.out.println(a==b);//true } 而a.equals(b)先判断a == b是否成立,再判断b是否是String类,然后逐个比较value数组的值是否相等。equalsIgnoreCase在此基础上忽略大小写的区别 a.compareTo(b)比较a和b第一个不相等字符的差值,若都相等则比较长度差值。compareToIgnoreCase多一个忽略大小写的区别。regionMatches(int toffset, String other, int ooffset, int len)则是比较a从toffset开始和other从ooffset开始长度为len的部分是否相等。 startsWith(String prefix, int toffset)字符串从tooffset位置开始和prefix是否相等。endsWith(String suffix)字符串结尾和suffix等长部分是否相等。 hashCode()调用时,若hash值为0且字符串长度不为0,则要计算hash值,方法是value数组化为31进制 indexOf是返回第一个出现的指定值的位置,可以通过fromIndex来指定开始查找的位置,而indexOfSupplementary是忽略大小写的该方法。lastIndexOf则是从尾部开始查找最后一个。 substring根据指定的位置返回一个新的子字符串,若指定位置不符合原字符串的长度,则抛错。 a.concat(String str)新建一个字符串内容是a+str并返回,不会修改a原本的值 public static void main(String args[]) { String a, b; a = "123"; b = "123"; a.concat(b); System.out.println(a);//123 System.out.println(a.concat(b));//123123 a = a.concat(b); System.out.println(a);//123123 } replace(char oldChar, char newChar)生成一个新的字符串,将原字符串中的oldChar字符全部替换为newChar,不会改变原字符串的值。replaceAll(String regex, String replacement)和前一个方法相比,参数regex是正则表达式,其余相同。 public static void main(String args[]) { String a; a = "12131"; a.replace("1", "a"); System.out.println(a);//12131 a = a.replace("1", "a"); System.out.println(a);//a2a3a } split(String regex, int limit)将字符串按照给定的正则表达式分割为字符串组,limit是分割产生的数组最大数量,对于多余部分不做分割全部保留在最后一个字符串中。 public static void main(String args[]) { String a; a = "1,2,3,4"; String[] b = a.split(","); for(String t : b){ System.out.print(t + " ");//1 2 3 4 } System.out.println(""); String[] c = a.split(",", 3); for(String t : c){ System.out.print(t + " ");//1 2 3,4 } } toCharArray()复制出一个新的char[]而不是直接返回value trim()生成一个新的字符串,去掉头部的所有空格 public native String intern()这个方法的作用是在常量池当中寻找是否已经存在该字符串,若已存在则返回该引用,若不存在则在常量池新建。从上面的源码分析中,我们可以看出String的所有操作都是返回一个新的字符串,对自身是没有修改的,String被设计为一个不可变的final对象,理由有以下几点: 1. 字符串常量池的需要。字符串常量池的诞生是为了提升效率和减少内存分配。、因为String的不可变性,常量池很容易被管理和优化。 2. 安全性考虑。正因为使用字符串的场景如此之多,所以设计成不可变可以有效的防止字符串被有意或者无意的篡改。(通过反射或者Unsafe直接操作内存的手段也可以实现对所谓不可变String的修改)。 3. 作为HashMap、HashTable等hash型数据key的必要。因为不可变的设计,jvm底层很容易在缓存String对象的时候缓存其hashcode,这样在执行效率上会大大提升。 public static void main(String args[]) { String a, b; a = "123"; b = new String(a).intern(); System.out.println(a == b);//true a = "12" + "3"; b = "123"; System.out.println(a == b);//true a = "12" + "3"; b = new String("123"); System.out.println(a == b);//false a = "12" + "3"; b = new String("123").intern(); System.out.println(a == b);//true a = new String("123"); b = a.intern(); System.out.println(a == b);//false } 从上面一段代码的运行结果我们可以看到,intern()会从常量池寻找指定的字符串,指向同一个常量池对象的时候,a==b就是成立的。这里说明一下最后一个case,首先常量池存在了”123”,然后a获得的引用是另一个”123”(因为是new String得到的对象),而b得到的是常量池中第一个”123”的引用,所以a!=b。对于字符串相加的操作"12" + "3",操作过后常量池内会有3个字符串,"12" "3" “123” 个人GitHub地址: https://github.com/GrayWind33

优秀的个人博客,低调大师

java.lang.IndexOutOfBoundsException and drawPosText

package com.example.canvastest; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; /** * Created by 700 on 2018/7/31. */ public class DrawText_DrawPosText extends View{ private Paint mTextPaint; private float[] offset = new float[10]; public DrawText_DrawPosText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public DrawText_DrawPosText(Context context, AttributeSet attrs) { super(context, attrs); } public DrawText_DrawPosText(Context context) { super(context); } private void initView(){ for(int i = 0; i<10; i+=2){ offset[i] = 100; offset[i+1] = 250+150*i/2; } mTextPaint = new Paint(); mTextPaint.setColor(getResources().getColor( android.R.color.holo_blue_light )); mTextPaint.setTextSize(20);//设置文字大小 // mTextPaint.setTextAlign(Paint.Align.CENTER);//设置居中 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); initView(); canvas.drawText("hehehehehedadadadadadadada",100,100,mTextPaint); canvas.drawPosText("hehehehehedadadadadadadada",offset,mTextPaint); } } 郁闷。。报错的原因是数组超范围了。。 还以为是for语句写错了,看了半天。。。没错啊。。。 后来聚焦在了drawPosText()上面,觉得不太对劲,看了下源码,额。。。。。。, 意思是干嘛呢,drawPosText()不是第一个参数是字符串嘛,drawPosText()这个方法就是把这个字符串拆成一个一个字符,按顺序对应好第二个参数的位置放好。。。,也就是说我第二个参数offset这个数组长度是10,即包含着五个xy坐标对,只能描述五个位置,所以第一个参数只能是一个五字符的字符串,不然就跟数组不匹配,便会报错了。。。 喏,第一个参数改成是一个五字符的字符串: 也便成功运行了:

优秀的个人博客,低调大师

Java入门之继承(上)

继承 概念: 一种类与类之间的关系 使用已存在的类的定义作为基础建立新类 新类的定义可以增加新的数据或功能,也可以用父类的功能,但不能选择性地继承父类,需全部把父类的东西继承过来。 子类只能继承父类非私有成员 特点: 1.利于代码复用 2.缩短开发周期 语法: 1.使用extends实现继承 2.单一继承,只能有一个父类 /* * Dog 为子类 又名派生类 * Animal 为父类 又名 超类、基类 */ class Dog extends Animal{ } 方法重载要求: 1.同一个类中 2.方法名相同,参数列表不同(参数顺序 、个数 、类型) 3.方法返回值、访问修饰符 4.与方法的参数名无关 方法重写要求: 1.有继承关系的子类中 ,子类重写父类方法 2.方法名,参数类型、顺序、个数 都要与父类的方法相同 3.方法返回值类型与父类兼容就可以,允许发生改变 4.访问修饰符,访问范围需要大于等于父类的访问范围 5.与方法的参数名无关 访问修饰符 公有的 public (允许任意位置使用) 私有的 private (只允许在本类中使用) 受保护的 protected (允许在当前类、同包子类/非子类、跨包子类调用、跨包非子类不能允许) 默认 (允许在当前类 同包子类调用;跨包子类/非子类不允许调用) super关键字 super代表父类对象的引用,通过super访问父类的成员 父类的构造方法不允许被继承,不允许被重写,但是会影响子类实例化过程 继承后的初始化顺序(子类对象的实例化过程) 父类静态成员 → 子类静态成员 → 父类对象构造 → 子类对象构造 子类的构造的过程中必须调用其父类的构造方法 如果子类的构造方法中没有显示的标注,则系统默认调用父类的无参构造方法 如果子类的构造方法中既没有显示标注,且父类中没有无参的构造方法,则编译错误 使用super调用父类指定的构造方法,必须在子类构造方法的第一行 public Cat(String name, int age){ super(name, age); } this 和 super this : 当前类对象的引用 访问当前类的成员方法、成员属性 访问当前类的构造方法 不能在静态方法中使用 super 访问父类的成员方法、成员属性 访问父类的构造方法 不能在静态方法中使用 this和super不能同时使使用 在继承(下)中会学习更深入的知识,敬请期待,很快更新。

优秀的个人博客,低调大师

Java 基础 之 while 循环

http://www.verejava.com/?id=16992618818220 /* while 循环 while(表达式){} 如果表达式为true 继续执行,否则退出循环 */ public class Test1 { /** * @param args the command line arguments */ public static void main(String[] args) { // 输出 1 - 5 之间(包括 1,5 本身)的数. int n=1; while(n<=5) // while 判断条件true 执行循环代码, 否则终止循环 { System.out.println(n); n++; } } } http://www.verejava.com/?id=16992618818220

优秀的个人博客,低调大师

Java 基础 之 位运算

http://www.verejava.com/?id=16992602784016 public class Operation5 { public static void main(String[] args) { //位运算 /* 包括: 与 &, 或 |, 取反 ~, 异或 ^ 带符号左移<<, 带符号右移 >>, 无符号右移 >>> 1. & 就是二进制位如果都是1则为1,否则为0 2. | 就是二进制位如果都是0则为0,否则为1 3. ~ 就是二进制位如果是0取反变成1,否则如果是1取反变成0; 4. ^ 就是运算两边二进制位两边同时相等时为0,否则为1 5. <<就是将二进制位逐位向左移动n位,后面补n个0,相当于乘2; 6. >>就是将二进制位逐位向右移动n位,前面补n个符号位,向当于除2; 6. >>>就是将二进制位逐位向右移动n位,前面补n个0 */ byte a=1; //二进制 00000001 byte b=8; //二进制 00001000 byte c=127; //二进制 01111111 byte d=-127;//二进制 10000001 System.out.println(a&b); //结果 00000000 System.out.println(a|b); //结果 00001001 2^3+2^0=9 System.out.println(~a); //结果 11111110补码 转换为原码=10000001=-1-1=-2 System.out.println(a^b); //结果 00001001 =9; System.out.println(a<<1); //结果 00000010 2^1=2 System.out.println(c<<1); //结果 11111110 =254 System.out.println(a>>1); //结果 00000000 =0 System.out.println(c>>1); //结果 00111111 =63 System.out.println(d>>1); //结果 11000000补码 原码=10111111=-63-1=-64 System.out.println(d>>>1);//结果 01000000原码 /* 注意: 1.计算机存储时 二进制第一位是表示符号位 1 代表负数, 0代表正数 2.计算机存储时以补码的方式存储的, 正数的补码跟原码一样,负数的补码是去掉第一位符号位取反然计算结果后 再 + 1 得到的. 3. 那补码转换成原码就反过来 去掉第一位取反计算结果后 再-1. 4. System.out.println 没有 System.out.println(byte b)方法,计算机先自动将byte转化成 int 然后在移动 */ } } http://www.verejava.com/?id=16992602784016

优秀的个人博客,低调大师

Java之解压流(ZipInputStream)

一、ZipInputStream相对于ZipOutputStream而言,使用上面简单的多了,相对的,既然存在压缩流,就会存在,解压的方式。 二、解压文件,流的使用过程中也是很常用的,在读取文件,根据文件类型进行处理,这样,就可以做到,最低成本的数据传输了 三、解压例子 /** * 提供给用户使用的解压工具 * @param srcPath * @param outPath * @throws IOException */ public static void decompressionFile(String srcPath, String outPath) throws IOException { //简单判断解压路径是否合法 if (!new File(srcPath).isDirectory()) { //判断输出路径是否合法 if (new File(outPath).isDirectory()) { if (!outPath.endsWith(File.separator)) { outPath += File.separator; } //zip读取压缩文件 FileInputStream fileInputStream = new FileInputStream(srcPath); ZipInputStream zipInputStream = new ZipInputStream(fileInputStream); //解压文件 decompressionFile(outPath, zipInputStream); //关闭流 zipInputStream.close(); fileInputStream.close(); } else { throw new RuntimeException("输出路径不合法!"); } } else { throw new RuntimeException("需要解压的文件不合法!"); } } /** * ZipInputStream是逐个目录进行读取,所以只需要循环 * @param outPath * @param inputStream * @throws IOException */ private static void decompressionFile(String outPath, ZipInputStream inputStream) throws IOException { //读取一个目录 ZipEntry nextEntry = inputStream.getNextEntry(); //不为空进入循环 while (nextEntry != null) { String name = nextEntry.getName(); File file = new File(outPath+name); //如果是目录,创建目录 if (name.endsWith("/")) { file.mkdir(); } else { //文件则写入具体的路径中 FileOutputStream fileOutputStream = new FileOutputStream(file); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); int n; byte[] bytes = new byte[1024]; while ((n = inputStream.read(bytes)) != -1) { bufferedOutputStream.write(bytes, 0, n); } //关闭流 bufferedOutputStream.close(); fileOutputStream.close(); } //关闭当前布姆 inputStream.closeEntry(); //读取下一个目录,作为循环条件 nextEntry = inputStream.getNextEntry(); } } 四、测试: public static void main(String[] args) throws IOException { decompressionFile("D:\\srv.zip", "D:\\test"); }

优秀的个人博客,低调大师

java之压缩流(ZipOutputStream)

一、文件压缩,是很有必要的,我们在进行文件,传输过程中,很多时候都是,都是单个文件单个文件发送接收,但是当数据量特别大,或者文件数量比较多的时候,这个时候就可以考虑文件压缩。 二、优势:文件压缩过后,只需要进行一次文件的传输就可以了。减少频繁发送的问题。缺点:文件大小会变大,如果传输过程中断了,风险较大。 三、实现: /** * 提供给用户使用的基本压缩类 * @param srcPath * @param outPath * @throws IOException */ public static void compressFile(String srcPath, String outPath) throws IOException { //读取源文件 File srcFile = new File(srcPath); //判断输出路径是否正确 File outFile = new File(outPath); //如果只是路劲加入对应的压缩名称 if (outFile.isDirectory()) { //用"/"作文判断标准 if (outPath.endsWith(File.separator)) { outPath += srcFile.getName().split("\\.")[0] + ".zip"; } else { outPath += File.separator + srcFile.getName().split("\\.")[0] + ".zip"; } } //读取文件流 FileOutputStream fileOutputStream = new FileOutputStream(outPath); ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream); //压缩文件 compressFile(srcFile, srcFile.getName(),zipOutputStream); //关闭流 zipOutputStream.close(); fileOutputStream.close(); } /** * 迭代方式进行文件压缩 * @param file * @param fileName * @param outputStream * @throws IOException */ private static void compressFile(File file, String fileName, final ZipOutputStream outputStream) throws IOException { //如果是目录 if (file.isDirectory()) { //创建文件夹 outputStream.putNextEntry(new ZipEntry(fileName+"/")); //迭代判断,并且加入对应文件路径 File[] files = file.listFiles(); Iterator<File> iterator = Arrays.asList(files).iterator(); while (iterator.hasNext()) { File f = iterator.next(); compressFile(f, fileName+"/"+f.getName(), outputStream); } } else { //创建文件 outputStream.putNextEntry(new ZipEntry(fileName)); //读取文件并写出 FileInputStream fileInputStream = new FileInputStream(file); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); byte[] bytes = new byte[1024]; int n; while ((n = bufferedInputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, n); } //关闭流 fileInputStream.close(); bufferedInputStream.close(); } } 四、测试: public static void main(String[] args) throws IOException { compressFile("D:\\srv", "D:\\"); } 五、效果还是可以,此方式根据需要修改!

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册