zoukankan      html  css  js  c++  java
  • Java SE 第二篇

    二、  Java SE 第二篇

    1.  Arrays 数组

    // 声明一维数组,[]内不允许有值
    int[] arr;
    int arr[];
    // 创建一维数组对象,[]内必须有值
    arr = new int[6];
    // 对一维数组元素的初始化,动态初始化用 for 循环
    int arr[] = {1, 2, 3};// 静态初始化;
    
    // 声明二维数组
    int[][] arr;
    // 创建二维数组对象
    arr = new int[3][4];
    // 对二维数组元素的初始化,动态初始化用双重 for 循环
    int[][] a = {
                  {1,2},
                  {3,3,4,4},
                  {5,6,7}
    };// 静态初始化
    
    // Arrays 常用方法
    Arrays.toString(arr);// 返回数组元素
    Arrays.sort(arr);// 从小到大排序
    Arrays.binarySearch(arr, number);// 对有序数组进行二分查找 number,并返回其对应的索引
    Arrays.copyOf(char[] original, int newLength);// 复制指定数组,并赋予新的数组长度,底层是:System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); + return copy; System.arraycopy(arr01, 2, arr02, 0, 6);// 数组 arr01 从下标为 2 的元素开始的 6 个元素拷贝到目标数组 arr02 中 Arrays.fill(arr, 2, 4, 100);// 将 arr 中下标 [2, 4) 的元素替换成 100

     

    2.  String 不可变字符序列

    // 声明
    String str;
    // 创建字符串对象
    str = new String();
    // 初始化
    String str = "abcdefg";
    String str = new String("abcdefg");
    // 常用方法
    str.charAt(1);// 该下标对应的内容 
    str.equals(str02);
    str.equalsIgnoreCase();// 忽略大小写的比较
    str.length();
    str.indexOf("a");// 从左往右数碰到的第一个"a"的位置
    str.lastIndexOf("a");// 从右往左数碰到的第一个"a"的位置
    str.substring(int beginIndex, int endIndex);// 打印【beginIndex,endIndex)的字符
    str.replace(a,b);// 将字符串中所有的 a 替换成 b
    str.split("*");// 按"*"切割成数组
    str.trim();// 去除首尾空格
    str.startsWith("ab");// 判断是否以"ab"开头
    str.endsWith("ab");// 判断是否以"ab"结尾
    str.toLowerCase();// 转换成小写字母
    str.toUpperCase();// 转换成大写字母

     

    3.  StringBuilder & StringBuffer 可变字符序列

    1. 与 String 类不同的是,StringBuffer 和 StringBuilder 类的对象在被多次的修改后,不产生新的对象
    2. StringBuilder 线程不安全,效率高
    3. StringBuffer 线程安全,效率低
    4. 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,直到该线程读取完,其他线程才可使用,因而不会出现数据不一致或者数据污染
    5. 线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
    6. 由于 StringBuilder 效率较高,所以多数情况下建议使用 StringBuilder 类;然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类
    
    public class Test01 {
        public static void main(String[] args) {
            StringBuilder sb = new StringBuilder();// 默认字符数组容量初始为 16,看源码
            StringBuilder sb1 = new StringBuilder(32);// 字符数组容量初始为 32,看源码
            StringBuilder sb2 = new StringBuilder("abcd");// 字符数组容量初始为 20(4+16),相当于在数组添加结束符:value[]={'a', 'b', 'c', 'd', , ,...}
            
            sb2.append("efg");// 追加方法
            System.out.println(sb2);
    System.out.println(sb2.hashCode()); sb2.append(
    true).append(321).append("可变字符序列");// 通过 return this; 实现方法链,看源码 System.out.println(sb2);
    System.out.println(sb2.hashCode()); } }
    // 结果: abcdefg
    // 366712642
    // abcdefgtrue321可变字符序列
    // 366712642
    public class Test02 { public static void main(String [] args){ StringBuilder sb = new StringBuilder("abcdefghijklmn"); sb.delete(1, 3);// 删除下标【1, 3)的元素 System.out.println(sb); sb.delete(1, 3).delete(1, 3);// 利用 return this; 实现方法链 System.out.println(sb); sb.reverse();// 反转字符串 System.out.println(sb); } } // 结果: adefghijklmn // ahijklmn // nmlkjiha

    // 为了更深入了解 StringBuilder,让我们分析一下 StringBuilder 的部分源码
    // StringBuilder 继承于 AbstractStringBuilder(AbstractStringBuilder 实现了 Appendable 接口, CharSequence 接口的部分方法)
    public final class StringBuilder
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    {  
        // 无参构造器,调用了父类有参构造器,初始化字符数组容量为 16
        public StringBuilder() {
            super(16);
        }
        
        public StringBuilder(int capacity) {
            super(capacity);
        }
        
        public StringBuilder(String str) {
            super(str.length() + 16);
            append(str);
        }
    
        @Override
        public StringBuilder append(Object obj) {
            return append(String.valueOf(obj));
            /* 这里我们给出 java.lang.String 类定义的 valueOf()方法
               public static String valueOf(Object obj) {
                   return (obj == null) ? "null" : obj.toString();
               }
            */
        }
    
        @Override
        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }
    }
    // 从上面可以看出 StringBuilder 类的大部分方法都是继承自 AbstractStringBuilder,所以我们直接看 AbStractStringBuilder 类是怎么样实现这些方法的
    abstract class AbstractStringBuilder implements Appendable, CharSequence {
        char[] value;// 底层用的是 char 数组来存储数据
        int count;// 字符串长度
        
        // 无参构造器
        AbstractStringBuilder() {
        }
    
        // 有参构造器,用于初始化 char 数组的容量
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
    
        // 返回字符串长度
        @Override
        public int length() {
            return count;
        }
        
        // 返回字符数组的容量
        public int capacity() {
            return value.length;
        }
        
        // 追加方法
        public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);// 判断是否需要扩容
            str.getChars(0, len, value, count);// 底层是:System.arraycopy(str, 0, value, count, len - 0);
            count += len;
            return this;
        }
    
        private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            if (minimumCapacity - value.length > 0) {
                value = Arrays.copyOf(value, newCapacity(minimumCapacity));// 底层是:System.arraycopy(value, 0, copy, 0, Math.min(value.length, newCapacity)); + return copy;
            }
        }
    
        private int newCapacity(int minCapacity) {
            // overflow-conscious code
            int newCapacity = (value.length << 1) + 2;// 新容量 = old容量 * 2 + 2
            if (newCapacity - minCapacity < 0) {
                newCapacity = minCapacity;
            }
            return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity;
        }
    
        private int hugeCapacity(int minCapacity) {
            if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
                throw new OutOfMemoryError();
            }
            return (minCapacity > MAX_ARRAY_SIZE) ? minCapacity : MAX_ARRAY_SIZE;
        }
    }
    StringBuilder

    4.  Date 日期

    // 创建日期
    Date date = new Date();
    date.getTime();// 毫秒数
    // 等同于
    long t = System.currentTimeMillis();// 毫秒数
    Date date = new Date(t);
    
    // 日期格式化
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd 'at' hh:mm:ss,属于本月的第 W 周的 E");
    /**
     * SimpleDateFormat("yyyy-MM-dd");
     * y 年
     * M 月
     * d 日
     * w 这年的第 w 周 
     * W 这个月的第 W 周
     * E 星期几
     * h 时
     * m 分
     * s 秒
     * S 毫秒
     * a 上午/下午
     */
    String str = format.format(date);// 将时间对象按照格式转成字符串
    Date date = format.parse(str);// 将格式化字符串转成时间对象

    5.  Calendar 日历

    注意:
     * 1.月份:一月是0,二月是1,... 十二月是11
     * 2.星期:周日是1,周一是2,... 周六是7
    
    // 创建
    Calendar c = new GregorianCalendar();
    
    // 设置
    c.set(2019, 6, 2, 15, 02, 00);
    //
    c.set(Calendar.YEAR, 2019);
    c.set(Calendar.MONTH, 6);
    c.set(Calendar.DATE, 2);
    //
    c.setTime(new Date());
    
    // 加时
    c.add(Calendar.HOUR, 3);// 加3个小时
    c.add(Calendar.MINUTE, 10);// 加10分钟
    c.add(Calendar.SECOND, 00);
    
    // 可视化日历
    public class VisualCalendar {
        public static void main(String[] args) {
            String temp;
            System.out.println("Please put in the Time-Format as:"+"yyyy-MM-dd");
            Scanner scanner = new Scanner(System.in);
            temp = scanner.next();
            
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                System.out.println("日	一	二	三	四	五	六");
                Date date = format.parse(temp);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                int d = calendar.get(Calendar.DATE);
                calendar.set(Calendar.DATE, 1);
                int e = calendar.get(Calendar.DAY_OF_WEEK);// 得到6月1号是星期几
                int Maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);// 得到6月最大天数
                for(int i=1;i<e;i++)
                    System.out.print("	");
                for(int j=1;j<=Maximum;j++){
                    if(calendar.get(Calendar.DATE)==d)
                        System.out.print("*"+j+"	");
                    else
                        System.out.print(j+"	");
                    if(calendar.get(Calendar.DAY_OF_WEEK) == 7)
                        System.out.println();
                    calendar.add(Calendar.DATE, 1);    
                }    
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }
    /* 运行结果:
    Please put in the Time-Format as:yyyy-MM-dd
    2019-6-2
    日    一    二    三    四    五    六
                                       1    
    *2    3     4     5    6     7     8    
    9     10    11    12   13    14    15    
    16    17    18    19   20    21    22    
    23    24    25    26   27    28    29    
    30    
    */

    6.  File 文件

    // 创建 File 对象
    File file = new File("URL");
    
    // 常用方法
    file.isFile();// 判断是否是文件
    file.isDirectory();// 判断是否是目录
    file.canWrite();// 是否可写
    file.canRead();// 是否可读
    file.exists();// 是否存在
    file.length();// 读取文件的大小,即文件所占字节数 file.mkdirs();// 父目录不存在时,创建父目录,再创建指定目录 file.mkdir(); // 父目录不存在时,不创建指定目录 file.createNewFile();// 在指定目录下创建指定文件,若文件已存在返回 false file.delete();// 删除指定文件,不能删除目录
    file.deleteOnExit();// 退出即删除,用于临时文件 file.listFiles();// 返回一个抽象路径名数组 file.getName();// 获取文件名称或最后一级目录的名称
    file.getPath();// 获取文件或目录的路径
    file.getAbsolutePath();// 获取绝对路径
    file.isAbsolute();// 是否是绝对路径
    file.getParent();// 获取最近的父目录名称
    file.renameTo(dest);// 重新命名,也可以做移动操作 //用递归方法遍历指定目录的各级目录和文件 public class Test { public static void main(String[] args) { System.out.println("Please put in the searched-directory of what you want :"); Scanner scanner = new Scanner(System.in); String str = scanner.nextLine(); File file = new File(str); printFile(file, 0); } static void printFile(File file, int lever){ for(int i=0;i<lever;i++) System.out.print("-"); System.out.println(file.getName()); if(file.isDirectory()){ File[] fs = file.listFiles(); for(File temp : fs) printFile(temp,lever+1); } else return ; } } /* 运行结果 Please put in the searched-directory of what you want : E:/test test -.idea --inspectionProfiles -a.txt -b.txt -c.txt -dir --study ---数学 ----01.txt ---英语 ----02.pub ---语文 ----03.xlsx -k.txt */

     

    7.  == 和 equals() 有何区别?

    在这之前,我们先了解以下几个要点
    * 1.栈内存:用于存放基本数据类型的变量、对象的引用(地址)、数组的引用(首地址)
    * 2.堆内存:用于存放所有 new 出来的对象
    * 3.常量池:用于存放字符串常量和基本类型常量(public static final)
    // 基本数据类型的比较 int a = 1; int b = 1; System.out.println(a==b);// 返回值为 true // 对象的比较 Object o1 = new Object(); Object o2 = new Object(); System.out.println(o1==o2);// 返回值为 false // 以上说明 == 是对两个基本数据类型变量的值作比较,对两个对象的地址作比较 // 因为在 Java 中,一切对象都继承于 Object 类,要了解 equals 方法,我们不妨看看它在 Object 源码中是如何定义的 public boolean equals(Object obj) { return (this == obj); } // 由此可见 equals 方法在 Object 中就是用 == 作的比较,即对两个对象的地址作比较 // 较为特殊的,String 对 Object 对象的 equals 方法进行了重写,源码如下 public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } // 由此可见 String 重写的 equals 方法最终会对 String 对象的内容作比较

    // 结论:在比较基本数据类型时,我们直接用 == 就可以;在对两个对象作比较时,可以通过重写 equals 方法来满足我们的需求
  • 相关阅读:
    JavaScript 事件对象Event的工具类
    高度组件专一性的松耦合系统CI的MVC
    [转]解决PHP相对目录问题最有效的办法
    CodeIgniter 用户登录注册模块
    记录js的四种函数写法
    Firebug 控制台API
    jQuery实战(一)
    apache:一个ip绑定多个域名的问题(续)
    JavaScript 字符串操作(一)
    hdu 1166 敌兵布阵【树状数组入门】
  • 原文地址:https://www.cnblogs.com/IT-LFP/p/10962883.html
Copyright © 2011-2022 走看看