zoukankan      html  css  js  c++  java
  • java学习笔记-基础篇

    Java基础篇

    1—12 常识

    13 this关键字

    14参数传递

    16 继承

    17 访问权限

    28—31异常

    1—12 常识

    1.文件夹以列表展示,显示扩展名,在地址栏显示全路径

    2.javac编译 java运行

    3.java开发环境 

    java编辑器 ( integrated development environment) IDE  集成开发环境

    常见的Jbuilder、eclipse

    4.double d1,d2,d3=0.123   //不表示d1 d2 d3都是0.123

    5.程序执行过程中 对内存的处理  将内存分成4个区域 code segment 、 data segment  、stack  、heap

    print和println的区别    println表示此处换行打印

    shift+table键的使用 :批量修改缩进/Alt+/开启自动提示

    代码不够健壮 只完成了功能 对于用户输入的很多情况没有考虑

    方法(method)中的return  代表方法返回  执行到return 表示方法结束

    属性 attribute  就是成员变量

    哪些类 类的属性和方法 类与类之间的关系

    web service和soa  究竟谁赢了(显然是web service赢了)

    约定俗称的命名规则:

    类名首字母大写   方法名和变量名首字母小写  运用驼峰标识(每个单词首字母大写)

    包命名方式   package   公司名称倒过来就行 com.xxx.test

    访问控制符 或者叫权限修饰符

    继承关键字  extends

    人机交互方式:一种是通过图形界面,一种是通过命令行(即cmd)

    常用dos命令

    dir

    cd  回到根目录

    cd. . 回到上级目录

    md 文件名    新建目录

    cd  目录名    进到指定目录

    Java两大核心机制—JVM和GC,有了各平台版本的JVM(如UNIX平台版本、Linux平台版本),java代码在可以一次编译,运行在多个平台上。

    10%-3=1  对负数取模可忽略不计,结果仍为正

    -10%3=-1  被模的数为负数,结果为负

    -10%-3=-1

    &&

    ||   短路与  短路或  如果前边的判断为真或为假  则后边的不进行判断

    从键盘读取用户输入,使用Scanner类中的方法:

    import java.util.Scanner;  第一步导入Scanner类

    public class TestScanner{

             public static void main(String[] args) {

                       Scanner scanner = new Scanner(System.in);   第二步声明一个Scanner对象

                       System.out.println("Please enter number1");

                       int a;

                       a = scanner.nextInt();    第三步使用nextInt()方法

    }

    case 10:

    case 9:

    10和9这两个标签,可以共用一个代码块

    /*

    *输入2013年的某个月份和日期,例如month=4 day=21

    *经过程序计算,打印出输入的月份和日期是2013年的第几天

    *TestSwitch.java

    */

    System.out.println();   //直接可以打印换行

    break  continue的用法 

    int[] a =null  数组a的声明

    System.out.println(a.length)   在未分配内存空间时 使用数组的属性 会报空指针异常

    a=new int[10]  为数组a分配内存空间

    多维数组

    int  t[][] = new int[4][]   

    t[0] = new int[5]

    t[1] = new int[3]

    方法(即函数)中,可以写

    return;

    但是这行代码之后的代码都不会被执行

    类的实例化

    Person p = new Person()

    p1和p2是Person的两个对象,操作任何一个的(非静态)成员变量都不会对另一个产生影响。

    对象的生命周期:

    匿名对象

    new Person().shout();

    出现在:只使用一次,经常将匿名对象作为实参传递给一个函数调用。

    信息的封装和隐藏

    将属性声明为私有的(private),再提供公开的(public) 方法:getXXX和setXXX方法来操作成员变量。

    构造器与类同名且没有返回值(连void都没有)。

    方法的重载

    在同一个类中允许存在多个同名的方法

    方法名不同,返回值类型可以相同也可以不同,参数列表(个数或类型)不一样。

    13 this关键字

    this是对调用当前方法的那个当前对象的引用

    this的用途:指代的是当前对象

    1 在一般的方法中可以通过this来引用当前对象的成员(方法、属性)

    2 通过this() 调用重载的构造器,需要注意的是,这行代码必须放在重载构造器的第一行。

     

    14参数传递

    基本数据类型的参数传递和引用类型的参数传递  两者区分

    16 继承

    extends关键字

    注意:子类不能继承父类私有(private)的成员和方法:不能直接访问。

    构造器的继承在Super关键字中讲解。

    17 访问权限

    Private  仅在类的内部访问

    Defalut  仅在包的内部访问

    Protected  在子类中该属性可以被访问,可以跨包访问

    Public    访问权限最高,无论是否在一个包内,是否是子类,都可以访问

    18 方法的重写和覆盖

    28 异常

    Java运行过程中发生的异常事件可以分为两类:

    Error:JVM系统内部错误(无能为力)

    Exception:其他因编程错误或偶然的外在因素导致的一般性问题(可以避免),例如:

    空指针

    访问不存在的文件

    网络异常

    ArithmeticException:被除数为0的异常

    ArrayIndexOutOfBoundsException:数组下边越界异常

    ClassCastException:类型转换异常

    NullPointerException:空指针异常,引用指向null,但是使用了这个引用的属性或方法

    Java采用异常处理机制,将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁易维护。

    抓抛模型

    抛出(throw)捕获(catch)

    一个异常回到main(),main()也不进行处理的话,程序会中止

    我们通常可以处理Exception,而对Error无能为力

    29 处理异常

    try....catch...finally...

    在捕获异常时 注意父类参数

    可以有多个catch

    问题:如果一个语句块中有两种异常,并且也写了两个catch来捕获不同类型的异常,那么这两个catch都会进去吗?还是,有多个catch的情况,只要有一个捕获到了,后边的catch都不进去了?

    finally语句始终会被执行

    运行时异常和编译时异常

    IO异常属于编译时异常

    30 声明抛出异常

    使用throws关键字声明抛出异常(抛出即不做处理,由调用者处理)

    throws方法抛出的异常可以是方法中出现的异常的类型或其父类类型

    throws可以声明抛出多个类型的异常,多个异常使用逗号分隔

    运行时异常不需要使用throws关键字声明抛出

    重写方法不能抛出比重写范围更大的异常

    31 人工抛出异常

    使用throw关键字,人工手动抛出异常的步骤:

    1 创建一个异常类对象

    RuntimeException ex = new RuntimeException();

    2 把异常类对象抛出去

    throw  ex;

    自定义的异常类:

    1 通常继承自RuntimeException(可以继承Exception)

    2 自定义的异常类就是用来被人工抛出的

    32 Collection接口

    1 创建一个Collection接口的对象

    Collection collection = new ArrayList()

    2 Collection重要方法说明

    2.1 添加

    collection.add(new Person())

    Collection collection2 = new AyyayList()

    collection2.add(new Person())

    collection.addall(collection2)

    System.out.println(collection.size())

    2.2 用于访问集合的方法:

    获取集合的长度:size()

    对集合进行遍历的方法:iterator()可以得到对应的Iterator接口对象

    Iterator:迭代器

    获取Iterator接口对象

    使用while循环和Iterator对象遍历结合中的每一个元素,具体使用Iterator接口的hasNext()和nex() 方法

    Iterrator iterator = collection.iterator()

    while(iterator.hasNext()){

             Object obj = iterator.next();

             System.out.println(obj)

    }

    2.3 移除集合中的元素

    remove():移除某一个指定的对象,通过equals()方法比较集合中是否存在该元素,以及是否能成功移除

    removeAll()

    clear():使集合中的元素置空

     

    2.4 用于检测集合的方法

    retains()

    retainsAll()

    isEmpty()

    2.5 其他方法

    toArray()

    T [] to Array(T[]):涉及到泛型,后面再讲

    equals():比较两个集合是否相等

    hashCode()

    使用增强for循环的方式对集合进行遍历

    for(Object obj:collection){

             System.out.println(obj)

    }

    33 Set接口

    是collection的子接口,Set集合不允许包含相同元素,比较是否相同使用equals()

    HashSet

    1.1 基本特征

    不能保证元素的排列顺序

    HashSet不是线程安全的

    集合元素可以是null

    对于HashSet:如果两个对象通过equals() 方法返回true,这两个对象的hashcode值也应该相同

    LinkedHashSet

    按插入顺序排序

    34  TreeSet

    自然排序和定制排序

    自然排序

    1 如果使用TreeSet()无参数的构造器创建一个TreeSet对象,则要求放入其中的元素的类必须实现Comparable接口,所以,在其中不能放入null元素

    2 必须放入相同类的对象,否则会发生类型转换异常

    3 两个对象通过Comparable接口compareTo(Object obj)方法的返回值来比较大小,并进行升序排序

    4 当需要把一个对象放入TreeSet中,重写该对象对应的equals()方法时,应保证该方法与compareTo(Object obj)方法有一致的结果

    定制排序

    1 创建TreeSet对象时,传入Comparator接口的实现类

    Set set2 = new TreeSet(comparator); //comparator已经实现了Comparator接口,并重写了其中的compare方法

    要求:Comparator接口的compare方法的返回值和两个元素的equals()方法具有一致的返回值

    35  List

    list有序、可重复

    以下为4种排序方法

         //iterator遍历

          Iterator iterator = list.iterator();

          while(iterator.hasNext()){

             System.out.println(iterator.next());

          }

         

          //for增强遍历

          for(Object obj:list){

             System.out.println(obj);

          }

          //for遍历

          for(int i = 0 ; i < list.size(); i ++){

             System.out.println(list.get(i));

          }

          //ListIterator遍历

          ListIterator lit = list.listIterator();

          while(lit.hasNext()){

             System.out.println(lit.next());

          }

    Arrays.asList(new Person("MM",30),new Person("NN",40))

     

    36 Map

    Key Value

    Key不允许重复

    //给map添加元素:put或put(map)

          map.put("1", new Person("AA",12));

          map.put("1", new Person("BB",25));

          map.put("2", new Person("CC",36));

          map.put("3", new Person("DD",42));

          map.put("4", new Person("EE",68));

         

          /*

          //从map中取出元素(遍历)

          //先取出键,再根据键取出值

          Set keyset = map.keySet();

          for(Object key:keyset){

             Object value = map.get(key);

             System.out.println(key + ":" + value);

          }

         

          //直接取出值集合

          Collection values = map.values();

          for(Object val:values){

             System.out.println(val);

          }

          //直接取出键值对

          for(Map.Entry<String, Object> entry:map.entrySet()){

             String key = entry.getKey();

             Object value = entry.getValue();

             System.out.println(key + ":" + value);

          }

          */

         

          //移除元素

          map.remove("5");

         

          //工具方法:size() contains() isEmpty()

          System.out.println(map.size());

          System.out.println(map.containsKey("1"));

          System.out.println(map.isEmpty());

    37 Collections工具类和Enumeration

    使用collections的sort方法对List中的元素进行排序

    Collections.sort(list, new Comparator(){

     

             public int compare(Object o1, Object o2) {

                Person p1 = (Person) o1;

                Person p2 = (Person) o2;

                return p1.getAge() - p2.getAge();

             }

           });

    }

    //获取线程安全的List对象,使用synchronizedList()

    List list2 = Collections.synchronizedList(new ArrayList());

    //对Enumeration对象进行遍历

                       Enumeration names = Collections.enumeration(list);

         

          while(names.hasMoreElements()){

             Object obj = names.nextElement();

             System.out.println(obj);

          }

    38 泛型

    不使用泛型的两个问题:

    1 放入集合中的可以是任何类型

    2 取出时需要进行强制类型转换

    使用泛型 可以解决这个问题 不是任意类型的list  而是一个Person类型的list

    List<Person> persons = new ArrayList();

     

    Person [] personArray = persons.toArray(new Person[0]);

     

    Map<String,Person> personMap = new HashMap<String,Person>();

          personMap.put("111", persons.get(0));

          personMap.put("222", persons.get(1));

          personMap.put("333", persons.get(2));

          personMap.put("444", persons.get(3));

          personMap.put("555", persons.get(4));

         

          for(Map.Entry<String, Person> entry: personMap.entrySet()){

             System.out.println(entry.getKey() + ": " + entry.getValue());

          }

    39 定义泛型

    public class Dao<T>{

      

       public T get(Integer id){

          T result = null;

          return result;

       }

      

       public void save(T entity){

         

       }

    }

    40 继承与泛型

    String为Object类型的子类,则String[] 也是Object[] 的子类;

    Object [] obj = new String[]{"11","22"};

    但,String为Object类型的子类,List<String>并不是List<Object>的子类

    List<String> strlist = Arrays.asList("AA","SS");

    List<Object> objlist = strlist;  

    //编译时会提示cannot convert from List<String> to List<Object>

    泛型通配符

          List<Student> stus = new ArrayList<Student>();

          stus.add(new Student("AA",12,"zhengdaUniversity"));

         

          printPersonInfo(stus);

         

       }

      

       public static void printPersonInfo(List<? extends Person> persons){

          for(Person person:persons){

             System.out.println(person);

          }

       }

    41 泛型方法

    把指定类型的数组中的元素放入到指定类型的集合中

    泛型方法:在方法声明时,同时声明泛型,在方法的返回值,参数列表以及方法中都可以使用泛型类型

    42 枚举类

    枚举类:一个类的对象是有限且固定的;因此不能在类的外部创建类的对象;类内部的属性都是常量;在类的内部创建对象,但需要在类的外部能够访问到该对象,而且不能被修改

    private Season(String name,String desc){

          this.name = name;

          this.desc = desc;

       }

       private final String name;

       private final String desc;

      

       public static final Season SPRING = new Season("春天","春风又绿江南岸");

       public static final Season SUMMER = new Season("夏天","春风又绿江南岸");

       public static final Season FALL = new Season("秋天","春风又绿江南岸");

       public static final Season WINTER = new Season("冬天","春风又绿江南岸");

    也可以使用enum关键字来定义枚举类

    public enum Season2 {

       //必须在枚举类的第一行写出有哪些枚举值

       SPRING("春天","春天好美啊"),

       SUMMER("夏天 ","夏天很美"),

       FALL("秋天","秋天很美"),

       WINTER("冬天","冬天很冷");

       private final String name;

       private final String desc;

    43 注解

    @Override

    @Deprecated

    @SuppressWarnings

     

    自定义Annotation

    1 使用@interface定义注解

    2 使用类似于接口方法声明的方式来定义注解的属性;其中返回值为属性的类型,方法名为属性的名称

    提取Annotation信息

    在反射内容时讲解

    44  IO

    File类

    public class IOTest {
    
        @Test
        public void testFile() throws IOException {
            //新建一个文件对象,该文件应已被创建
            File file = new File("hello.txt");
            //访问文件的名字
            String name = file.getName();
            System.out.println(name);
            //访问文件的绝对路径
            String path = file.getAbsolutePath();
            System.out.println(path);
            //将文件剪切到其他地方
    //        file.renameTo(new File("d:\hello.txt"));
            //文件监测相关方法
            System.out.println(file.exists());
            File dir = new File("HaHa");  //新建目录对象,该目录应事先已创建
            System.out.println(dir.isFile());
            
            //获取文件的常规信息
            System.out.println(file.length());
            
            //文件操作
            File file2 = new File("abcd.txt");  //新建文件
            file2.createNewFile();
        }
    
    }

     还可以通过mkDir()方法新建目录

    IO流的分类

    InputStream&Reader

    InputStream和Reader是所有输入流的基类

        @Test
        public void testInputStream() throws IOException {
            //创建一个字节输入流
            InputStream in = new FileInputStream("hello.txt");
            //读取文件内容
            //.1读取一个字节,效率很低 -1表示读到文件结尾
    //        int result = in.read();    
    //        while(result != -1){
    //            System.out.print((char)result);
    //            result = in.read();
    //        }
            
            //.2一次读取一组字符
            byte [] buffer = new byte[10];
            int len = 8;
            
            //返回读取的字节数,若为-1表示读到文件的结尾
    //        while((len = in.read(buffer)) != -1){
    //            //这样读 可能会出现错误 有可能最后不够8个字符
    ////            for(byte b:buffer){
    //            //这样读可以避免以上错误
    //            for(int i = 0; i < len; i++){
    //                System.out.print((char)buffer[i]);
    //            }
    //        }
            
            //.3 把内容读取到字节数组的部分连续的元素中
            byte [] result = new byte[1024*10];
            //2表示读取in这个字节流从头开始的2个字符,result是被读取后存放字节的数组,0表示从result的起始位置开始存放
            in.read(result, 0, 2);
            for(int i = 0; i < result.length; i++){
                System.out.print((char)result[i]);
            }
        
        in.close(); //关闭流文件
         
      }
    @Test
        public void testReader() throws IOException {
            Reader reader = new FileReader("hello.txt");
            
            char[] buffer  = new char[10];
            int len = 10;
            
            while((len = reader.read(buffer)) != -1){
                for(int i = 0 ;i < len; i++){
                    System.out.print(buffer[i]);
                }
            }
            
            reader.close();
    
        }

    OutputStream&文件复制

    OutputStream和Writer,是所有输出流的基类

    @Test
        public void testOutputStream() throws IOException {
            //输出字节流 abcd.txt应已经创建
            OutputStream out = new FileOutputStream("abcd.txt");
            //需要写入的字符
            String content = "www.test.com.hahahahhahah.hahahah.hahahhahahhahahahahhahahahhahahah";
            
            byte[] buffer = new byte[10]; //这里的buffer只声明了10个字节,但发现可以容纳任意字节
            //将字符转换成字节
            buffer = content.getBytes();
            //下面的写法也可以
    //        for(int i = 0 ; i < buffer.length; i++){
    //            out.write(buffer[i]);
    //        }    
            //直接这样就可以写入
            out.write(buffer);
            //写入一部分字符
            out.write(buffer, 0, 10);
            
            out.close();    
            
        }
    /*
         * 利用字节输入输出流,完成hello.txt文件的复制,将该文件复制为hello2.txt
         * 除文本文件外,还可以复制二进制文件;字符流只能处理文本文件
         * */
        @Test
        public void testCopyFile() throws IOException {
            //.1创建定位到hello.txt的文件输入流
            InputStream in = new FileInputStream("hello.txt");
            //.2创建定位到hello2.txt的文件输出流
            OutputStream out = new FileOutputStream("hello2.txt");
            //.3创建一个byte数组,用于读写文件
            byte [] buffer = new byte[1024*10];
            int len = 0;
            //.4读写文件
            while((len = in.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            //.5关闭流资源
            in.close();
            out.close();
        }
    利用字符输入输出流,完成hello.txt文件的复制,将该文件复制为hello2.txt
    public class IOTest2 {
    @Test
    public void testCopyFile() throws IOException { //.1 声明输入输出流 Reader in = new FileReader("hello.txt"); Writer out = new FileWriter("hello2.txt"); //.2 创建一个字符数组 char [] buffer = new char[10]; //.3 利用循环读取源文件,并向目标文件写入 //.4 注意使用的写入方法:write(cbuf, off, len) //而不能直接使用write(cbuf) int len = 0; //in.reader()返回读取到的字符的个数,到达结尾时返回-1 while((len = in.read(buffer)) != -1){ out.write(buffer, 0, len); } //.5 关闭流资源 in.close(); out.close(); } }

    缓冲流

    BufferedInputStream和BufferedOutputStream

    BufferedReader和BufferedWriter

    /*
         * 复制hello.txt到hello3.txt*/
        @Test
        public void testBufferedReaderAndBufferedWriter() throws IOException{
            //.1 创建BufferedReader和BufferedWriter
            Reader in = new FileReader("hello.txt");
            BufferedReader bufferedReader = new BufferedReader(in);
            
            Writer out = new FileWriter("hello3.txt");
            BufferedWriter bufferedWriter = new BufferedWriter(out);
            
            //.2 进行读写操作
            String buffer = null;
            
          int i = 0 ;
            
            while((buffer = bufferedReader.readLine()) != null){
                if (i != 0) {
                    bufferedWriter.write("
    ");
                } 
                bufferedWriter.write(buffer);
                i++;
            }
            
            //.3 关闭流:只需要关闭包装流,节点流会会在内部关闭
            bufferedReader.close();
            bufferedWriter.close();
        }
        /*
         * 利用BufferedInputStream和BufferedOutputStream完成
         * hello.txt到hello4.txt的复制*/
        @Test
        public void testBufferedInputStreamAndBufferedOutputStream() throws IOException{
            InputStream inputStream = new FileInputStream("hello.txt");
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            OutputStream outputStream = new FileOutputStream("hello4.txt");
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
            
            byte [] buffer = new byte[10];
            int len = 0 ;
            
            while((len = bufferedInputStream.read(buffer)) != -1){
                bufferedOutputStream.write(buffer, 0, len);
            }
                
            bufferedInputStream.close();
            bufferedOutputStream.close();
        }

    转换流

    InputStreamReader和OutputStreamWriter

        /*
         * 利用转换流InputStreamReader*/
        @Test
        public void testInputStreamReader() throws IOException{
            //指向文档的字节流
            InputStream in = new FileInputStream("hello.txt");
            //把上面的流转换为字符流
            Reader reader = new InputStreamReader(in);
            //把字符流转换为带缓冲的字符流
            BufferedReader bufferedReader = new BufferedReader(reader);
            
            String str = null;
            while((str = bufferedReader.readLine()) != null){
                System.out.println(str);
            }
            
            //关闭
            in.close();
            reader.close();
            bufferedReader.close();
        }
        /*
         * 先创建两个字节输入输出流:分别指向:hello.txt hello5.txt
         * 然后再转为字符输入输出流
         * 再转为带缓冲的字符输入输出流
         * 
         * 完成文件的复制*/
        @Test
        public void testOutputStreamWriter() throws IOException{
            InputStream in = new FileInputStream("hello.txt");
            OutputStream out = new FileOutputStream("hello5.txt");
            
            Reader reader = new InputStreamReader(in);
            Writer writer = new OutputStreamWriter(out);
            
            BufferedReader bufferedReader = new BufferedReader(reader);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            
            String buffer = null;
            int i = 0;
            
            while((buffer = bufferedReader.readLine()) != null){
                if (i != 0) {
                    bufferedWriter.write("
    ");
                }
                bufferedWriter.write(buffer);
                i++;
            }
            
            bufferedReader.close();
            bufferedWriter.close();
        }
        
        

    对象流

    ObjectInputStream和ObjectOutputStream

    .1)序列化需要实现Serializable接口

    .2)类A下的某个字段是引用类型,引用的是类B,则类B必须实现Serializable接口,否则类A不能被序列化

    在实际开发中,框架中已包含了此部分代码,不需要我们自己写

    public class Person implements Serializable {
        
        /**
         * 类的版本号,用于对象的序列化,具体用于读取对象时比对硬盘上对象的版本和
         * 程序中对象的版本是否一致,若不一致读取失败,并抛出异常
         */
        private static final long serialVersionUID = 1L;
    往硬盘文件写内容
    @Test
    public void testSerializable() throws IOException { Person person = new Person("Lily",26); OutputStream outputStream = new FileOutputStream("hello.txt"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(person); outputStream.close(); objectOutputStream.close(); }
    从硬盘文件读取    
    @Test
    public void testOnjectInputStream() throws IOException, ClassNotFoundException { InputStream inputStream = new FileInputStream("hello.txt"); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); Object obj = objectInputStream.readObject(); System.out.print(obj); objectInputStream.close(); inputStream.close(); }

     RandomAccessFile类

     RandomAccessFile及可以读取文件内容,也可向文件输入内容

    @Test
        public void testRandomAccessFile() throws IOException {
            //.1创建一个RandomAccessFile对象
            RandomAccessFile randomAccessFile = new RandomAccessFile("hello.txt", "rw");
            //.3读取文件内容
            String str = null;
            while((str = randomAccessFile.readLine()) != null){
                System.out.println(str);
            }
            //设置指针位置,会覆盖从指针开始位置的待增加字符串长度的字符
            randomAccessFile.seek(10);
            //.4向文件写内容 在文件结尾增加字符串
            randomAccessFile.writeBytes("append...");
            //.2关闭RandomAccessFile对象
            randomAccessFile.close();
        }
    /*
         * 向hello.txt文件中插入一行:www.baidu.com
         * 插入到第二行,原内容下移*/
        @Test
        public void testRandomAccessFile() throws IOException {
            RandomAccessFile access = new RandomAccessFile("hello.txt", "rw");
            //先读一行
            String line = access.readLine();
            //这里有疑问,怎么能确保读到buffer中的是除第一行之外的字符呢?又
            //没有将指针定位到第一行结尾
            byte[] buffer = new byte[(int)(access.length()-line.length())];
            access.read(buffer);
            
            access.seek(line.length());
            //写入要写的字符
            access.writeBytes("
    HH
    ");
            //再写入先前的内容
            access.write(buffer);
            access.close();
        }

    45 Java常用类

    1 String是不可变的字符序列

    2  关于字符串缓冲池:直接通过=为字符串赋值,会先在缓冲池中查找有没有一样的字符串,如果有就把那个引用赋给字符串变量,否则,会创建一个新的字符串,并把它放入缓冲池

    3 字符串的几个常用方法:

    3.1 去除前后空格的trim()方法

    3.2 求子字符串的方法:subString()

    从fromIndex开始,包含fromIndex,且String的字索引从0开始

    3.3 subString(fromIndex,toIndex):[fromIndex,toIndex)

    3.4 indexOf:求指定字符的索引

    3.5 spilt(String regex):把字符串拆分成字符数组

    3.6 equals():比较字符串内容是否相等必须使用该方法,不能直接使用==

    StringBuffer和StringBuilder

    StringBuffer和StringBuilder是可以被修改的字符序列

    append()方法:追加字符

    注意:append()方法的返回值还是当前的StringBuffer对象,可以使用方法的连缀

    StringBuilder.append("a")

                   .append("b")

                         .append("c")

    2). StringBuffer, StringBuilder 是可变的字符序列.

        > StringBuffer 是线程安全的, 所以效率较低.

        > StringBuilder 是线程不安全的, 效率较高. 大部分时使用 StringBuilder.

    Date()封装了日期和时间

    1. DateFormat是一个抽象类

    抽象类获取对象的方式:

    1) 创建其子类对象

    2) 有的抽象类中提供了静态工厂方法来获取抽象类的实例

    -SimpleDateFormat

            如果需要把 Date 类型的对象格式化为一个字符串, 或把一个字符串转为一个 Date 对象则使用 DateFormat.

       

        //1. 调用静态工厂方法来获取 DateFormat 对象.

        //传入的参数是日期或时间的样式.    

             DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,

                                                   DateFormat.LONG);

                               

             Date date = new Date();

             //格式化日期对象的 format 方法

             String dateStr = dateFormat.format(date);

             System.out.println(dateStr);

            

             dateStr = "2013年6月10日 下午03时48分06秒";

             //解析字符串到日期对象的 parse 方法.

             Date date2 = dateFormat.parse(dateStr);

             System.out.println(date2); 

            

             //创建 SimpleDateFormat 对象.

             DateFormat dateFormat =

                                         new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  

    Random和Math

    Random中封装了随机相关的方法:返回随机的基本数据类型的值

    Math:中封装了常用的数学方法

    小结

    4. 集合:

    1). Collection
    ①. List:
    ②. Set:

    2). Map:
    3). Iterator:
    4). Collections, Arrays:

    3. 泛型:

    1). 在集合中使用泛型: List<Person> persons = new ArrayList<>();
    2). 定义泛型类: class Dao<T, PK>{}. 在泛型类中可以像使用其他类型那样使用泛型类型.
    3). 泛型和继承:
    ①. List<Object> 不是 List<Person> 的父类!
    ②. 通配符: List<? extends Object> list 可以指向 List<Object> 或 List<Person>
    注意: 带有通配符的泛型集合中不能添加除 null意外的任何元素.
    4). 定义泛型方法: public static <E> E get(E e, Integer id){...}

    2. IO:

    1). 类:

    InputStream FileInputStream BufferedInputStream ObjectInputStream
    OutputStream FileOutputStream BufferedOutputStream ObjectOutputStream
    Reader FileReader BufferedReader InputStreamReader
    Writer FileWriter BufferedWriter OuputStreamWriter

    2). 最常用的方法:

    ①. 文件的复制.

    InputStream in = new FileInputStream(fileName);
    OutputStream out = new FileOutputStream(fileName2);

    byte [] buffer = new byte[1024 * 10];
    int len = 0;

    while((len = in.read(buffer)) != -1){
    out.write(buffer, 0, len);
    }

    in.close;
    out.close;

    ②.

    BufferedReader bufferedReader =
    new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));

    3). 序列化:
    ①. 序列化的意义:
    ②. 如果需要对某个类的对象实现序列化: 则该类需要实现 Serializable 接口. 且该类的所有字段也必须
    是可被序列化的.

    4). RandomAccessFile: 类中有一个指向文件内容的指针. 通过 seek() 方法来移动指针.
    可以完成对文件的读写操作.

    1. 关于常用类:

    1). String 是一个不可变的字符序列!
    2). StringBuffer, StringBuilder 是可变的字符序列.
    > StringBuffer 是线程安全的, 所以效率较低.
    > StringBuilder 是线程不安全的, 效率较高. 大部分时使用 StringBuilder.
    3). Date: 封装了时间和日期.
    4). DateFormat
    -SimpleDateFormat
    如果需要把 Date 类型的对象格式化为一个字符串, 或把一个字符串转为一个 Date 对象
    则使用 DateFormat.

    //1. 调用静态工厂方法来获取 DateFormat 对象.
    //传入的参数是日期或时间的样式.
    DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
    DateFormat.LONG);

    Date date = new Date();
    //格式化日期对象的 format 方法
    String dateStr = dateFormat.format(date);
    System.out.println(dateStr);

    dateStr = "2013年6月10日 下午03时48分06秒";
    //解析字符串到日期对象的 parse 方法.
    Date date2 = dateFormat.parse(dateStr);
    System.out.println(date2);

    //创建 SimpleDateFormat 对象.
    DateFormat dateFormat =
    new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    5). Random & Math

    46 反射

    一般在框架中会使用到反射

    有3种方式可以得到Class对象

    /**
         * 关于Class:
         * 1.Class是一个类
         * 2.对象照镜子后可以得到的信息,某个类的数据成员名、方法和构造器
         * 某个类到底实现了哪些接口
         * 3.对于每个类而言,JRE都为其保留一个不变的Class类型的对象
         * 4.一个Class对象只能由系统建立对象
         * 5.一个类在JVM中只会有一个Class实例
         * @throws ClassNotFoundException 
         * 
         */
        
        @Test
        public void testClass() throws ClassNotFoundException{
            Class clazz = null;
            
            //1.得到Class对象
            //1.1直接通过类名.class的方式得到
            clazz = Person.class;
            
            //1.2 通过对象调用getClass()方法来获取
            Person person = new Person();
            clazz = person.getClass();
            
            //1.3 通过全类名的方式获取,用的较多
            String className = "com.test.lesson12.Person";
            clazz = Class.forName(className);
                    
        }
    /**
         * Class类的newInstance()方法
         * 
         */
        @Test
        public void testNewInstance() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            String className = "com.test.lesson12.Person";
            Class clazz = Class.forName(className);
            
            //利用Class对象的newInstance()方法来创建类的一个对象
            //实际调用的是Person类的无参数的构造器,在声明类的时候无参数的构造器是必要的
            //一般一个类若声明了有参数的构造器,还应声明一个无参数的构造器
            Object obj = clazz.newInstance();
            
        }

     类加载器

    @Test
        public void testClassLoader() throws ClassNotFoundException{
            
            String className = "com.test.lesson12.Person";
            //1.获取一个系统的类加载器
            ClassLoader classLoader = ClassLoader.getSystemClassLoader();
            System.out.println(classLoader);
            
            //2.获取系统类加载器的父加载器
            classLoader = classLoader.getParent();
            System.out.println(classLoader);
            
            //3. 获取扩展类加载器的父加载器
            classLoader = classLoader.getParent();
            System.out.println(classLoader);
            
            //4.测试当前类由哪个类加载器进行加载
            classLoader = Class.forName(className).getClassLoader();
            System.out.println(classLoader);
            
            //5.测试JDK提供的Object类由哪个类加载器负责加载
            classLoader = Class.forName("java.lang.Object").getClassLoader();
            System.out.println(classLoader);
            
            //6.关于类加载器的一个主要方法
            //调用getResourceAsStream获得类路径下的文件对应的输入流
            InputStream in = null;
            in = this.getClass().getClassLoader().getResourceAsStream("com/test/lesson12/test.properties");
            System.out.println(in);
        }

     method:

    /*Class是一个对类的描述
         * Method:指定类中的方法
         * 1.获取Method
         * 1.1获取类的方法的数组:clazz.getDeclaredMethods()
         * 1.2获取类的指定的方法:
         * clazz.getDeclaredMethod("setName", String.class)
         * 方法名 方法的参数类型列表
         * 
         * 1.3通过method对象执行方法:
         * Object obj = clazz.newInstance();
            method.invoke(obj, "设置的name");
         *
         * */
        @Test
        public void testMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            String className = "com.test.lesson12.Person";
            Class clazz = Class.forName(className);
            
            //1.clazz对应的Person类的方法,但不能获取private方法
            Method[] methods = clazz.getMethods();
            for (Method method:methods) {
                System.out.println(method.getName());
            }
            
            //2.获取类对象的所有方法,包括private方法,且只获取当前类声明的方法
            Method[] methods2 = clazz.getDeclaredMethods();
            for (Method method:methods2) {
                System.out.println(method.getName());
            }
            
            //3.获取指定的方法
            Method method = clazz.getDeclaredMethod("setName", String.class); //1个String类型的参数
            System.out.println(method);
            
            Method method2 = clazz.getDeclaredMethod("test"); //无参数的private方法
            System.out.println(method2);
            
            Method method3 = clazz.getDeclaredMethod("setName", String.class,Integer.class);// 两个参数
            System.out.println(method3);
            
            //4.执行方法
            Object obj = clazz.newInstance();
            method.invoke(obj, "设置的name");
        }

     其余小节未细看:

    3). 尚硅谷_佟刚_Java基础_ 反射_获取并执行父类中定义的私有方法

    4). 尚硅谷_佟刚_Java基础_反射_使用 Method 的工具方法、

    5). 尚硅谷_佟刚_Java基础_ 反射_Field

    47 线程

    获取当前线程:Thread.currentThread().getName()

    /*
     * 1 在Java中,Thread类代表一个线程
     * 
     * 2.实现线程有2种方式:
     * 2.1继承Thread类
     * 2.2实现Runnable接口
     * 
     * 3.继承Thread类:
     * 3.1必须重写run()方法,里边放置的实际的线程体
     * 
     * 4.启动线程:
     * 4.1创建Thread对象
     * 4.2 调用Thread对象的start()方法启动线程,而不是run()方法
     * 
     * 5 实现Runnable接口的方式:
     * 5.1创建实现Runnable接口的实现类:必须实现run()方法
     * 5.2创建5.1对应的Runnable接口的实现类对象
     * 5.3创建Thread对象,利用Thread(Runnable target)
     * 5.4 调用Thread类的start()方法启动线程
     * 
     * */
    
    public class threadTest {
        
        public static void main(String[] args) {
            Thread thread = new FirstThread();
            thread.start();
            
            String threadName = 
                    Thread.currentThread().getName();
            for (int i = 0; i < 100; i++) {
                System.out.println(threadName + ":" + i);
            }
    
        }
    
    }
    
    class FirstThread extends Thread{
        /*线程体在run()方法中*/
        @Override
        public void run() {
            String threadName = 
                    Thread.currentThread().getName();
            for (int i = 0; i < 100; i++) {
                System.out.println(threadName + ":" + i);
            }
        }
    }

    以下三种方式实现:使用两个线程共同打印1—100

    /*不考虑线程安全的问题:
     * 使用Thread类,创建两个线程,共同打印0——99
     * */
    
    public class PrintNumber {
    
        public static void main(String[] args) {
            
            int i = 0;
            
            MyThread thread1 = new MyThread("Thread1");
            MyThread thread2 = new MyThread("Thread2");
            
            MyThread.setI(i);
            
            thread1.start();
            thread2.start();
        
        }
    
    }
    
    class MyThread extends Thread{
        //给线程创建一个静态参数
        private static int i;
        
        public static void setI(int i) {
            MyThread.i = i;
        }
        
    
        public MyThread(String threadName) {
            super(threadName);
        }
        
        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            
            for (; i < 100; i++) {
                System.out.println(threadName + ":" + i);
            }
        }
    }
    public class PrintNumber2 {
        int i = 0 ;
        
        public static void main(String[] args) {
            PrintNumber2 printNumber = new PrintNumber2();
            
            MyThread2 thread1 = new MyThread2("thread1", printNumber);
            MyThread2 thread2 = new MyThread2("thread2",printNumber);
            
            thread1.start();
            thread2.start();
    
        }
    
    }
    
    class MyThread2 extends Thread{
        PrintNumber2 printNumber;
        
        public MyThread2(String threadName,PrintNumber2 printNumber) {
            super(threadName);
            this.printNumber = printNumber;
        }
        
        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            
            for (; printNumber.i < 100; printNumber.i++) {
                System.out.println(threadName + ":" + printNumber.i);
            }
        }
    }
    public class MyRunnable implements Runnable {
        
        int i = 0;
        public void run() {
            String threadName = Thread.currentThread().getName();
            
            for (; i < 100; i++) {
                System.out.println(threadName + ":" + i);
            }
        }
        
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
            
            Thread thread1 = new Thread(myRunnable);
            Thread thread2 = new Thread(myRunnable);
            
            thread1.start();
            thread2.start();
            
        }
        
    }

     线程的生命周期

    New(新建状态) Runnable(可执行状态,有权获得CPU控制权,正在等待) Running(执行状态,已获得CPU控制权)

    Dead(死亡状态,使用isAlive方法判断是否死亡,已经死亡的线程不能再调用start()方法,否则会抛异常)

    1)yield()方法 主动让出CPU控制权 回到等待状态 

    2)sleep(int mills)方法  使线程休眠一段时间 以ms为单位

    3) join()方法 当前线程调用其他线程的join方法,当前线程将被挂起,进入阻塞状态,等待另一个线程执行完毕

    4)interrupt()  解除线程的阻塞状态 会抛出InterruptedException

    5)isAlive() 

    线程调度

    1)线程的优先级

    setPriority() (一般不使用这种方法来进行优先级设置)getPriority()

    共有10个优先级 整数值越大优先级越高 每个线程都有1个默认优先级 主线程的优先级是5

    3个常量:MIN_Priority  MAX_Priority  NORM_Priority

    线程同步

    实现如下效果:

    小强 拿走了1个苹果
    还剩下4个苹果
    小强 拿走了1个苹果
    还剩下3个苹果
    小明 拿走了1个苹果
    还剩下2个苹果
    小强 拿走了1个苹果
    还剩下1个苹果
    小强 拿走了1个苹果
    还剩下0个苹果
    小强 的线程结束了
    小明 的线程结束了

    public class ThreadTest2 implements Runnable {
        
        int appleNum = 5;
    
        public static void main(String[] args) throws InterruptedException {
            ThreadTest2 threadTest2 = new ThreadTest2();
            
            Thread th1 = new Thread(threadTest2);
            Thread th2 = new Thread(threadTest2);
            
            th1.setName("小强");
            th2.setName("小明");
            
            th1.start();
            th2.start();
            
        }
        
        boolean getApple(){
            //将以下代码锁起来,同一时刻只允许一个线程使用
            synchronized (this) {
                if(appleNum > 0){
                    System.out.println(Thread.currentThread().getName() + " 拿走了1个苹果");
                    appleNum = appleNum - 1;
                    System.out.println("还剩下" + appleNum + "个苹果");
                    return true;
                }
                
                return false;
            }        
            
        }    
        
        public void run() {
                while(appleNum > 0){
                    getApple();
                }    
                
                if(getApple() == false){
                    System.out.println(Thread.currentThread().getName() + " 的线程结束了");
                }
        }
    
    }

    线程安全问题

    1)多个线程使用同一个资源导致,使用synchronized代码块(称为同步块)解决线程安全的问题

    2)也可以使用synchronized 关键字定义方法,称为同步方法

    线程通信

    1)wait()方法

    2)notify()  notifyAll()方法 唤醒等待中的线程 这些方法都需要在同步方法中调用

    /*
     * 张飞有1张20元钞票 刘备和关羽各有1张5元钞票 售货员已有1张5元钞票 票值5元
     * */
    
    public class TicketHouse implements Runnable{
        
        private int fiveCount = 1;
        private int twyCount;
        public synchronized boolean buyticket(){  //该方法使用synchronized修饰
            String buyerName = Thread.currentThread().getName();
            if("zf".equals(buyerName)){
                if(fiveCount < 3){
                    System.out.println("张飞来买票了,当前的五元钞票已有" + fiveCount + "张,不够找零,请您等待");
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    }
                System.out.println("张飞来买票了,当前的五元钞票已有" + fiveCount + "张");
                fiveCount = fiveCount -3 ;
                twyCount = twyCount + 1;
                System.out.println("卖给张飞一张票,目前五元钞票剩下" + fiveCount + "张;目前二十元钞票有" + twyCount + "张");
            }else if("gy".equals(buyerName)){
                System.out.println("关羽来买票了,当前的五元钞票已有" + fiveCount + "张");
                fiveCount = fiveCount + 1;
                System.out.println("卖给关羽一张票,目前五元钞票剩下" + fiveCount + "张");
            }else if("lb".equals(buyerName)){
                System.out.println("刘备来买票了,当前的五元钞票已有" + fiveCount + "张");
                fiveCount = fiveCount + 1;
                System.out.println("卖给刘备一张票,目前五元钞票剩下" + fiveCount + "张");
            }
            
            if(fiveCount == 3){
                notifyAll();  //唤醒被暂停的线程,执行wait()后的代码
            }
    
            return false;
        }
    
        public void run() {
            buyticket();
        }
        
        public static void main(String[] args) {
            TicketHouse ticketHouse = new TicketHouse();
            
            Thread th1 = new Thread(ticketHouse);
            Thread th2 = new Thread(ticketHouse);
            Thread th3 = new Thread(ticketHouse);
            
            th1.setName("zf");
            th2.setName("gy");
            th3.setName("lb");
            
            th3.start();
            th2.start();
            th1.start();
        }
    
    }

     48 网络编程

    目的:直接或间接地通过网络协议与其他计算机进行通讯

    网络编程中主要有两个问题:

    1)如何准确地定位网络上一台或多台主机

    2)找到主机后如何可靠高效地进行数据传输

    常用的TCP/IP以其中的两个协议:TCP和IP协议而得名,实际上是一组协议,还包括其他一些协议

    传输控制协议TCP:先建立TCP链接,在传输完毕后,释放连接

    用户数据包协议:UDP

    端口号与IP地址和组合发出一个网络套接字(Socket) 端口号被规定为一个16位的整数0—65535  

    套接字能执行7种基本操作:

    —连接到远程主机

    —绑定到端口

    —接收从远程机器来的连接请求

    —监听到达的数据

    —发送数据

    —接收数据

    —关闭连接

    @Test
        public void testInetAddress() {
            InetAddress inetAddress;
            try {
                //使用getByName()方法
                inetAddress = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress);
            } catch (UnknownHostException e) {
                System.out.println("这个域名不存在");
                e.printStackTrace();
            }
            
        }

    客户端Socket的工作过程包括4个步骤:

    1)创建一个Socket

    2)打开连接到Socket的输入/出流

    3)按照一定协议对Socket进行读/写操作

    4)关闭Socket

    服务端Socket的工作过程包含4个步骤:

    1)调用ServerSocket(int port)创建一个服务器端套接字,并绑定到指定端口上

    2)调用accept(),监听连接请求

    3)调用Socket类的OutputStream和getInputStream获取输出流和输入流,开始网络数据的发送和接收

    4)关闭Socket

    Server端代码:

    @Test
        public void testServerSocket() throws IOException {
            ServerSocket serverSocket = new ServerSocket(8989);
            Socket socket = serverSocket.accept();
            
            OutputStream out = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(out);
            writer.write("来自服务端的问候哦");
            
            writer.close();
            out.close();
            
            socket.close();
            serverSocket.close();       
    
        }

     客户端代码:

    @Test
        public void testSocket() throws IOException {
            InetAddress  address = InetAddress.getByName("127.0.0.1");
            Socket socket = new Socket(address, 8989);
            
            InputStream in = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            
            System.out.println("O(∩_∩)O:" + reader.readLine());
                    
            reader.close();
            in.close();
            socket.close();
            
        }

     完成将服务器文件复制到本地:

    public class SocketTest {
        
        @Test
        public void testServerSocket() throws IOException {
            //新建一个ServerSocket,并设置监听请求
            ServerSocket serverSocket = new ServerSocket(8686);
            Socket socket = serverSocket.accept();
            //从程序到socket的输出流
            OutputStream out = socket.getOutputStream();
            //buffer用于存放从文件中读取出来的字符
            byte [] buffer = new byte[1024];
            int len = 0;
            //从文件到程序的输入流
            InputStream in = new FileInputStream("abc.jpg");
            //通过in从文件读入buffer,再从buffer通过out写入socket,客户端会通过socket接收
            while((len = in.read(buffer)) != -1){
                out.write(buffer, 0, len);
            }
            
            in.close();
            out.close();
            socket.close();
            serverSocket.close();
    
        }
        
        
        @Test
        public void testSocket() throws IOException {
            //客户端新建一个socket并绑定端口
            InetAddress address = InetAddress.getByName("127.0.0.1");
            Socket socket = new Socket(address, 8686);
            //从socket到程序
            InputStream in = socket.getInputStream();
            //buffer用于存放从程序到本地文件
            byte [] buffer = new byte[1024];
            int len = 0 ;
            //从程序到本地文件
            OutputStream out = new FileOutputStream("abcd.jpg");
            //通过in从socket读入buffer,再通过out将buffer写入文件
            while((len = in.read(buffer)) != -1){
                out.write(buffer, 0, len);
            }
            
            in.close();
            out.close();
            socket.close();
        }
        
    }

     UDP:不能保证数据是否能送达,也不能保证数据什么时候能送达,所以不建议使用

     URL编程:

    /*
         * 将网络资源下载到本地
         * */
        @Test
        public void testUrlConnection() throws IOException {
            URL url = new URL("http://127.0.0.1:8080/examples/test.txt");
            
            System.out.println(url.getPath());
            
            URLConnection urlConnection = url.openConnection(); 
            
            //将文件下载到本地
            InputStream in = urlConnection.getInputStream();
            OutputStream out = new FileOutputStream("text.txt");
            
            byte [] buffer = new byte[1024];
            int len = 0;
            
            while((len = in.read(buffer)) != -1){
                out.write(buffer, 0, len);
            }
        }

     至此,java基础篇结束。

  • 相关阅读:
    asp.net mvc学习(Vs技巧与Httpcontext)
    微信小程序代码构成
    MetaEditor中MQL使用方法
    lambda表达式中的排序问题
    Python Bs4 回顾
    Python操作Redis及连接方式
    C# for Python(Nugut Iron包)
    Jquery.ajax dataType参数
    Fleck For Web Socket
    visual studio git for coding
  • 原文地址:https://www.cnblogs.com/hnini/p/5328298.html
Copyright © 2011-2022 走看看