JavaSE——(三)常用类(StringBuffer,StringBuilder,数组常见操作(二分查找),Arrays,基本类型包装类)

一.StringBuffer和StringBuilder

1.来源

字符串广泛应用在Java 编程中,在 Java中字符串属于对象,Java 提供了String 类来创建和操作字符串。但是String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。所以就引入了两个新的类——StringBuffer类和StringBuild类。

2.使用
(1)构造方法
public StringBuffer():				无参构造方法
public StringBuffer(int capacity):	指定容量的字符串缓冲区对象
public StringBuffer(String str):		指定字符串内容的字符串缓冲区对象StringBuffer的方法:
public int capacity():返回当前容量。	理论值
public int length():返回长度(字符数)。 实际值
(2)添加,删除,替换和反转功能
- public StringBuffer append(String str):   可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
- public StringBuffer insert(int offset,String str):  在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身
- public StringBuffer deleteCharAt(int index):    删除指定位置的字符,并返回本身
- public StringBuffer delete(int start,int end):     删除从指定位置开始指定位置结束的内容,并返回本身
- public StringBuffer replace(int start,int end,String str):   从start开始到end用str替换
- public StringBuffer reverse():	字符串反转
(3)截取功能
- public String substring(int start):	 从指定位置截取到末尾
- public String substring(int start,int end):	  截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
//截取功能注意事项:这个方法的返回值值类型不再是StringBuffer本身,而是字符串类型。
(4)StringBuffer和String之间互相转换
  • String——StringBuffer
    • 通过构造方法:StringBuffer(String str)
    • 通过append()方法
  • StringBuffer——String
    • 通过构造方法:String(StringBuffer buffer)
    • 使用substring()方法
    • 使用toString()方法
(5)案例演示
//把数组中的的数据按照指定格式拼成一个字符串
package com.westo.demo1;
public class MyTest8 {
    public static void main(String[] args) {
        int arr[]={1,2,3,4};
        String str="[";
        StringBuffer stringBuffer = new StringBuffer(str);
        for (int i = 0; i < arr.length; i++) {
            if(i==arr.length-1){
                stringBuffer.append(arr[i]).append("]");
            }else{
                stringBuffer.append(arr[i]).append(",");
            }
        }
        String s = stringBuffer.toString();
        System.out.println(s);
    }
}
//将字符串反转
package com.westo.demo1;

import java.util.Scanner;
public class MyTest9 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个字符串");
        String s = scanner.nextLine();
        StringBuffer stringBuffer = new StringBuffer(s);
        System.out.println(stringBuffer.reverse());
    }
}
(6)StringBuffer和StringBuilder的区别
  • 相同点:StringBuffer和StringBuilder非常类似,均代表可变的字符序列,而且方法也一样。
  • 区别:StringBuffer是多线程操作字符串,而StringBuilder是单线程操作字符串。
  • 总结:所以StringBuffer在操作字符串上效率高,但安全性低。StringBuilder操作字符串时效率低,但安全性高。
(7)注意
  • StringBuffer类中并没有重写equals()方法。所以:
package com.westo.demo1;

class Demo {
    public static void main (String[] args) {
        StringBuffer buffer1 = new StringBuffer("String");
        StringBuffer buffer2 = new StringBuffer("String");
        if ( buffer1.equals(buffer2) ) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
}
//结果是:False

二.数组的常见操作

1.二分查找

二分查找只对已经排好序的数组有用

(1)思想
  • 二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.
  • 实现:给数组的头和尾设置一个标记,比如i=0;j=a.length-1,mid=(i+j)/2。如果x<a[mid],j=mid;如果x>a[mid],i=mid;然后重新计算mid1的值。
  • 用循环和递归都可以实现
(2)代码实现
package com.westmo.demo2;

import java.util.Scanner;

public class Search {
    public static void main(String[] args) {
        int arr[] = {1, 2, 3, 4, 5, 6};
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要查找的数");
        int i = scanner.nextInt();
        System.out.println(search(arr, i));
    }

    private static int search(int[] arr, int i) {
        int start = 0, end = arr.length - 1;
        int mid = (start + end) / 2;
        while (start <= end) {
            if(i==arr[mid]){
                return mid;
            }else if(i>arr[mid]){
                start=mid;
            }else if(i<arr[mid])
                end=mid;
            mid=(start+end)/2;
        }
        return -1;
    }
}
2.数组的其他排序方式

关于其他的排序方法(冒泡,快速,选择,插入,堆,希尔等)笔者博客中有专门的介绍。

三.Arrays

1.概述
  • Arrays是针对数组进行操作的工具类
  • 提供了排序,查找等功能
2.用法
- public static String toString(int[] a)
- public static void sort(int[] a)
- public static int binarySearch(int[] a,int key)
- static boolean equals(int[] a, int[] a2) 比较两个数组中的元素,是否一样
- static int[] copyOf(int[] original, int newLength)  复制旧数组中的元素到一个新的数组中,新的数组长度是newLength 从0开始复制旧数组
- static int[] copyOfRange(int[] original, int from, int to) 复制旧数组中的指定范围间的几个元素到新数组中

案例演示

package com.westmo.demo2;

import java.util.Arrays;
public class MyTest1 {
    public static void main(String[] args) {
        int arr[]={23,56,12,3,45,48,9};
        Arrays.sort(arr);//排序
        System.out.println(Arrays.toString(arr));//输出打印
        int i = Arrays.binarySearch(arr, 56);/查找元素56在数组中的索引位置
        System.out.println(i);
    }
}
Arrays类中的toString()方法和binarySearch()方法源码解析
   public static String toString(int[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";
        StringBuilder b = new StringBuilder();//用StringBuffer来进行字符串的拼接
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(a[i]);
            if (i == iMax)
                return b.append(']').toString();//拼接并转为String类型
            b.append(", ");
        }
    }
    
//可以看出binarySearch()方法采用的是二分查找的方法。
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                   int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;//位运算,效率更高
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

四.基本类型包装类

1.概述
  • Java中为了对基本数据类型进行更多,更方便的操作(比如将一个数转换为想要的进制),就提供了针对每一种基本数据类型提供了对应的类类型。
  • 基本类型和包装类类型的对应
    byte 		 Byte
	short			Short
	int			Integer
	long			Long
	float			Float
	double		        Double
	char			Character
	boolean		         Boolean
2.以Interger类为例介绍包装类的用法

(1)概述

  • Integer 类在对象中包装了一个基本类型 int 的值,
    该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,
    还提供了处理 int 类型时非常有用的其他一些常量和方法
  • public Integer(int value)
  • public Integer(String s) //要个一个字面上是数字的字符串,如果不是就会报错

(2)String类型和int类型相互转换

int -- String
	a:和""进行拼接
	b:public static String valueOf(int i)
	c:int -- Integer -- String
	d:public static String toString(int i)
String -- int
	a:String -- Integer -- intValue();
	b:public static int parseInt(String s)

案例演示

package com.westmo.demo2;

public class MyTest2 {
    public static void main(String[] args) {
        //int转为String
        int s=10;
        String s1 = s + "";
        String s2 = new String().valueOf(s);
        Integer integer = new Integer(s);
        String s3 = integer.toString(s);
        //String转为int
        String t="10";
        Integer integer1 = new Integer(t);
        int t1 = integer1.intValue();
        int t2= Integer.parseInt(t);
    }
}
3.自动装箱和拆箱

(1)概念

  • 自动装箱:把基本数据类型转换为包装类类型
  • 自动拆箱:把包装类类型转换为基本类型

(2)示例

 Integer i=100;//自动装箱
        i+=200;//自动拆箱
4.面试题
package com.westmo.demo2;
public class MyTest3 {
    public static void main(String[] args) {
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);
        System.out.println(i1 == i2);//false
        System.out.println(i1.equals(i2));//true


        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4);//false  创建新的对象,所以地址值肯定不同
        System.out.println(i3.equals(i4));//true

        Integer i5 = 128;
        Integer i6 = 128;
        System.out.println(i5 == i6);//它没有创建新的对象,为什么还是false呢?
        System.out.println(i5.equals(i6));//true

        Integer i7 = 127;
        Integer i8 = 127;
        System.out.println(i7 == i8);//true
        System.out.println(i7.equals(i8));//true
    }
}
  • 解析

new Integer()这种情况就不再说了,就讨论以下Integer x=…,的情况

  • Integer在与Integer比较的时候,由于直接赋值的时候会进行自动装箱,那么这里就要注意两个问题:
    • 当要赋的这个值是-128<=x<=127之间的数时,将会直接缓存在IntegerCache中,那么赋值的时候,就不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。
    • 当要赋的这个值不在这个范围时,就会直接new一个Integer对象。
      源码如下:
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++); 
        }
        private IntegerCache() {}
    }
发布了58 篇原创文章 · 获赞 13 · 访问量 1891

猜你喜欢

转载自blog.csdn.net/weixin_44324174/article/details/103775147