zoukankan      html  css  js  c++  java
  • Think in Java ---Chapter 13 字符串

    • String 对象是不可变的,JDK中String类的方法都是创建一个全新的String对象,即使是修改串的方法。可以用 == 运算观察一下。 String参数传递也是传递的引用的复制。
    • String不可变是源于这么一种思想:参数传递给方法是提供方法的信息的,而不是让方法改变参数的。
    • 任何指向String对象的引用都不可能改变他的值,因此引用之间就互不影响。但是不可变得特性会有效率问题。例如String仅有的两个重载操作符 ++= 。他们可以让String和各种类型的连接(基本类型会装箱,然后和引用型一样调用toString())。使用JDK自带的反编译工具javap -c 反编译后会发现String的+运算符实际上 使用了StringBuilder类完成可能的多个参数append()方法(一个参数调用一次),然后使用toString() 生成String对象。
    • Java不允许重载操作符。
    • 切记不要在循环中使用String的+或+= 方法,因为在每次循环中都会新建StringBuilder对象,append后toString 。而应该在循环外new一个StringBuilder对象。 。 sb.append(a + ":" + b); 也会让编译器掉入陷阱。
    • 因此,对字符串的任何拼接,都应该拆成对StringBuilder对象的单独参数的append操作。
    • 对编译器的的源码优化最好使用javap -c查看 。就能知道怎么写性能好了。
    • StringBuilder对字符串修改有丰富的方法,如insert, replace, substring,reverse,append,toString,delete。
    • 与StringBuffer相比,StringBuilder是线程不安全的,但是是可变字符串操作的首选工具类。
    • Java中的所有类根本上都是继承Object类,所以都有toString方法。容器类也是,而且容器类也复写了toString方法。例如ArrayList.toString方法会遍历成员逐个调用toString()方法。
    • 若希望toString打印出对象的内存地址,可以使用this关键字。例如:
    public class c{
        public String toString(){
            //  SHOULD BE super.toString()
            return "Class c address:" + this + "
    ";
        }
    
        public static void main(String args[]){
            List<c> v = new ArrayList<c>();
            for(int i = 0 ; i < 10; i ++){ v.add(new c()); }
            System.out.println(v);
        }
    
    }
    
    
    

    但是上面的 "Class c address:" + this + " " 会出现异常,因为编译器会先生成一个StringBuilder,然后append进每一个参数,当遇到 this 时,调用他的toString方法,于是发生了递归调用。
    所以,这就是因为多态造成的结果。所以要调用Object.toString()方法即可,即将 this 改成 super.toString()。

    • C语言中使用printf可以打印栈上的内容。
    • 熟记String的常用方法。
    • System.out.format() 和 System.out.printf() 方法是一样的。
    • Formatter类的使用:
      构造他的对象需要一个OutputStream、File或者PrintStream对象。然后就可以用format方法输出了。
    		Formatter f = new Formatter(System.out);
    		f.format("%s  %d", "asd",2);
    
    
    • 再复习一下printf的格式化规则。

    %[参数索引$][标志][宽度][.精确度]格式字母

    标志是例如 - ,表示左对齐方向。
    精确度用在String类型上表示打印的长度。不能用在整形上。

    • String.format() 方法类似C中的sprintf, 其内部使用了Formatter类。

    • Java中的正则比别的语言要多加一个'',例如 r‘d’ 表示数字。 换行和制表符之类的还是原样。

    • 相关方法:
      String对象.matches(正则式) //进行正则测试
      String对象.split(正则式) //按照正则式将字符串切分返回字符串数组
      String对象.replaceFirst(正则式) //
      String对象.replaceAll(正则式) //

    • java.util.regex 包中的Pattern类是正则类,(别的编程语言都是叫Regex)。
      其中,Pattern对象主要是用来对正则字符串进行编译或其他操作的类,还可以对字符串进行使用正则的切分。
      Matcher类包含有大量的匹配查询或者匹配替换等操作。

    		String regstr = "(.+?)\w\s";
    		Pattern p = Pattern.compile(regstr, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);  // 忽略大小写。元字符'.'匹配行终结符。开启多行查找,即元字符'^'和'$'匹配行头和行尾,平时这两个元字符匹配完整串的开始和结束。
    		
    		Matcher m = p.matcher("asddcdedd");
    		
    		while(m.find()){
    			System.out.println("find " + m.group(0) + m.start() );
    		}
    
    

    其中,Matcher对象的group(int gronum)和其他语言的正则类似,0表示全部匹配式,其他正数是分组号。start(int gronum)和end(int gronum)也类似。

    • 将JDK文档中正则类加入搜藏随时查询。

    • 正则复习: ?放在量词后表示非贪婪模式。放在元素后表示{1,}。

    • W D S 这种一般大写的表示非...。比如w表示单词, W表示非单词,即空白符。

    • Scanner的构造器可以接受任何类型的输入对象,包括File对象,InputStream,String字符串或者实现了Readable接口的类对象!!!。然后,就可以使用Scanner对象的nextXX()系列的方法将来自于各种输入源的流进行方便的读取。下面是各种读取的效果代码:

    		Scanner s = new Scanner("TRUE asd 213");
    		s.useDelimiter(" ");
    		System.out.println(s.nextBoolean());
    		System.out.println(s.next());
    		System.out.println(s.nextInt());
    		
    		File path = new File("test1.txt");
    //		BufferedWriter fw = new BufferedWriter(new FileWriter(path));
    //		fw.write("this.is.a.test.line");
    //		fw.flush();
    //		fw.close();
    //		s = new Scanner(path);
    //		s.useDelimiter("\.");
    //		while(s.hasNext()){
    //			System.out.println(s.next());
    //		}
    		
    		FileOutputStream fos = new FileOutputStream(path);
    		FileChannel fw = fos.getChannel();
    		ByteBuffer bb = ByteBuffer.allocate(256);
    		//bb.put(ByteBuffer.wrap("this.is.a.test.line".getBytes()));
    		CharBuffer cb_view = bb.asCharBuffer();
    		cb_view.put("this.is.a.test.line");
    		fw.write(bb);
    		fw.close();
    		fos.close();
    		s = new Scanner(path);
    		while(s.hasNext()){
    			System.out.println(s.next());
    		}
    
    //Output:
    //true
    //asd
    //213
    
    
  • 相关阅读:
    DevExpress ASP.NET v19.1版本亮点:Pivot Grid等控件
    .NET界面控件DevExpress全新发布v19.1.5|改进Office 2019主题
    Kendo UI for jQuery使用教程:操作系统/jQuery支持等
    Web安全篇之SQL注入攻击
    SQL Server中timestamp(时间戳)和rowversion(版本戳)
    PyCharm2019 激活码
    性能测试 vs 负载测试 vs 压力测试
    一套完整的压力测试项目文档
    Visual Studio性能计数器,负载测试结果分析- Part III
    Visual Studio进行负载测试,RIG和负载测试术语- Part II
  • 原文地址:https://www.cnblogs.com/yumingle/p/6692298.html
Copyright © 2011-2022 走看看