进阶语法

集合

TODO 集合
    
生活中也有集合的概念。是一个动词
Java中的集合是一个名词,数据的一种容器,用于容纳数据
Java提供了完整的集合框架
TODO 问题:什么时候需要一个容纳数据的容器,也就是集合对象?
           Java集合框架中就包含了对不确定个数的数据处理的集合类
TODO 问题:如果只是为了容纳数据,可以是直接使用数组,为什么要学习集合?
          数组使用起来不方便。在数据个数不确定的场合,数组使用起来不是很方便
TODO 总结:对不确定的有关系的数据进行相同的逻辑处理的场合,使用集合是一个不错的选择
TODO 根据数据的不同,Java的集合分为2大体系:
1. 单一数据体系 : Collection接口定义了相关的规则
2. 成对出现的数据体系 : Map接口定义了相关的规则
   所谓的成对的数据,就是2个数据有关系,可以根据第一个数据关联到第二个数据
   也称之为键值对数据 ,(123123, zhangsan) => (key, value)

容器类

1. Collection接口
   常用的子接口
   List :按照插入顺序保存数据,数据可以重复的
        具体的实现类: ArrayList, LinkedList
   Set : 集,无序保存,数据不能重复
        具体的实现类 HashSet
   Queue : 队列
        具体的实现类:ArrayBlockingQueue
2. Map接口
   具体的实现 : HashMap, Hashtable

集合 - Collection - List

TODO 集合 - Collection - List
           ArrayList : Array + List
               
TODO List : 列表,清单
     按照数据插入顺序进行存储
TODO Array : 数组,阵列
    
TODO 创建第一个集合对象:ArrayList  
	ArrayList list = new ArrayList(3);
	1. 不需要传递构造参数,直接new就可以,底层数组为空数组
    2. 构造参数需要传递一个int类型的值,用于设定底层数组的长度
    3. 构造参数需要传递一个Collection集合类型的值,用于将其他集合中的数据放置在当前集合中
        
TODO 增加数据
add方法可以增加数据,只要将数据作为参数传递到add方法即可
添加数据时,如果集合中没有任何的数据,那么底层会创建长度为10的数组
        list.add("zhangsan");


TODO 访问集合中的数据
获取集合中数据的条数
 	System.out.println(list.size());

获取指定位置的数据,可以采用索引的方式
 	System.out.println(list.get(1));

遍历集合中的数据
 for ( int i = 0; i < list.size(); i++ ) {
     System.out.println("集合中的数据:" + list.get(i));
 }


TODO 如果循环遍历集合数据时,不关心数据的位置,那么可以采用特殊的for循环
        for (循环对象:集合) {}
        for ( Object obj : list ) {
            System.out.println("集合中的数据:" + obj);
        }



TODO 修改数据
        将指定位置的数据进行修改,set方法需要传递2个参数,第一个参数表示数据的位置,第二个参数修改的值。
        方法会返回结果,这个结果就是更新前的值
        Object oldVal = list.set(1, "lisi");
        System.out.println("修改前的值:" + oldVal);



TODO 删除数据
将指定位置的数据进行删除,remove方法需要传递1个参数,参数表示数据的位置。
方法会返回结果,这个结果就是删除的值
        Object removeVal = list.remove(1);
        System.out.println("删除的值:" + removeVal);

TODO 打印集合对象
        System.out.println(list);

ArrayList的常用方法

add方法可以传递2个参数的,第一个参数表示数据增加的位置(索引),第二个参数表示数据
list.add(1, "zhaoliu");
把另外一个集合加入到该集合里面: list.addAll( otherList );

size方法表示集合内部数据的数量
System.out.println(list.size());

清空集合中的数据(全都不要,和removeall不同)
list.clear();

删除 指定 集合中的数据
list.removeAll(otherList);

判断集合中的数据是否为空
System.out.println(list.isEmpty());

用于判断集合中是否存在某条数据,返回布尔类型的值
System.out.println(list.contains("zhangsan123"));

用于获取数据在索引中的第一个位置,如果数据不存在,那么返回-1
System.out.println(list.indexOf("zhangsan123"));

复制新集合
Object[] objects = list.toArray();
Object clone = list.clone();//克隆出来的集合里面内容相同,但是数组类型为空,故需强转成ArrayLIst
ArrayList list1 = (ArrayList)clone;

LinkedList : Linked(连接) + List

LinkedList : Linked(连接) + List
构建集合对象
LinkedList list = new LinkedList();
增加第一个数据
list.addFirst("lisi");   //增加第一个数据
list.add(1, "wangwu");

 TODO 获取数据
  System.out.println(list.getFirst());  //获取第一个
  System.out.println(list.getLast());// 获取最后一个

TODO 获取数据(遍历数据)
System.out.println(list.get(1));
  for ( int i = 0; i < list.size(); i++ ) {
      System.out.println(list.get(i));
  }
  for ( Object obj : list ) {  //集合中的每一个数据都取出来,无规律
      System.out.println(obj);
  }

 修改数据
	list.set(1, "zhaoliu");

删除数据
	list.remove("zhangsan");

 TODO 打印集合数据
     System.out.println(list);


        // 想指定的位置增加数据
        list.add(1, "zhaoliu");
        list.addFirst("1");
       list.addLast("2");

        LinkedList list1 = new LinkedList();
        list1.add("zhangsan1");
        list1.add("lisi2");
       list1.add("wangwu3");
       list.addAll(list1);

        System.out.println(list.remove("1"));
        System.out.println(list.remove()); // 删除第一个
        list.removeFirst();删除第一个
       list.removeLast();删除最后一个
        list.remove(1);删除指定位置

        System.out.println(list.size());
        System.out.println(list.isEmpty());
        list.clear();//清空
        list.contains("1");//包含
        list.element(); // 获取第一个数据
      list.indexOf("");//获取数据的位置
       list.lastIndexOf("");//获取数据的最后一个位置
        list.push("aaa"); // 添加数据
        System.out.println(list.pop()); // 弹出数据

        System.out.println(list);

泛型语法

o instanceof  Person6   //判断o是否是Person6类型的

java todo 注解 java的todo_java

ArrayList<Person6> list = new ArrayList();
表示集合中只能存放Person6类型的集合,可以调用Person6相关内容,不能存放其它内容。
 
TODO 泛型和类型的区别
有时,也把泛型称之为类型参数,类型存在多态的使用方式,但是泛型没有多态的概念
①类型存在多态的使用
②泛型没有多态

Sort排序(集合)

// List对象进行排序,需要传递一个实现了比较器接口的对象
	list.sort(new NumberComparator());

//排序是需重写一个比较方法
class NumberComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        TODO  如果第一个数比第二个数大,那么返回结果为正数,表示升序
        return o1 - o2;
        
        TODO  如果第一个数比第二个数小,那么返回结果为负数,表示降序
        return o2 - o2;
        
        TODO  如果第一个数和第二个数一样大,那么返回结果为0

        
    }
}

集合 - Collection - Set

TODO LinkedList和ArrayList插入数据速率的比较
 增加第一条数据,LinkedList会比ArrayList快
 增加第二条数据,ArrayList会比LinkedList快
 增加第三条数据,ArrayList会比LinkedList快
 增加第四条数据(超过容量),LinkedList会比ArrayList快
 插入数据,LinkedList会比ArrayList快

HashSet

TODO 集合 - Collection - Set(面向单一数据)
 HashSet : Hash + Set  //存储是无序的
 Hash : 哈希算法,散列算法
 ArrayList : 数组
 LinkedList :底层不是数组
     
创建 HashSet set = new HashSet();

         TODo 增加数据
        set.add("zhangsan");
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");

        TODo 修改数据
		不能直接修改,只能先删除在增加
        TODo 删除数据
        set.remove("wangwu");

        TODo 查询数据
        for (Object o : set) {
            System.out.println(o);
        }


 TODO 集合 - Collection - Set  方法

        HashSet set = new HashSet();

        ArrayList list = new ArrayList();
		添加成员
        list.add("zhangsan");
        list.add("lisi");
        list.add("wamngwu");
        set.addAll(list);

		集合变成数组
        Object[] objects = set.toArray();

        System.out.println(set.isEmpty());
        //set.clear();
        set.contains("zhangsan");
        System.out.println(set.size());
        Object clone = set.clone();  //克隆,只包括里面的内容,不包括类的属性
        System.out.println(clone);

        System.out.println(set);
		

		HashSet 底层数据结构为 数组 + 链表

集合 - Collection - Queue

TODO 集合 - Collection - Queue
ArrayBlockingQueue : Array + Blocking(阻塞,堵住) + Queue
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);

add方法如果增加数据增加不了,直接发生错误。
queue.add("zhangsan");

 boolean zhangsan = queue.offer("zhangsan"); //offer()返回的是bool类型,成功为true
queue.poll()//取出队伍里第一个数据(可以理解成删除)
queue.take() //拿数据可以进行输出,但是拿出之后,后续代码不会执行,仍然是阻塞状态
queue.size()
queue.isEmpty()
queue.clear();
queue.contains()

集合 - Map

HashMap

TODO 集合 - Map(面向 (k,v)键值对数据)
HashMap : Hash + Map(底层:数组 + 单向链表)
数据存储是无序
HashMap map = new HashMap();

添加数据:put //map.put("zhangsan", "1");
修改数据,put方法也可以修改数据,返回值就是被修改的值(如果添加两个数据k值相等,则后添加的数据把前一个添加的数据覆盖掉,返回前一个的v值) 如果是第一次添加,返回值为空
    
        // TODO 查询数据
        System.out.println(map.get("zhangsan"));//得到v值

        // TODO 删除数据
        map.remove("zhangsan");

HashMap包括红黑树
		// 添加数据
		map.putIfAbsent("b", "2"); //不能覆盖,添加数据的时候如果里面没有与其k值相等的正常添加,如果有与其相等的则什么都不做

		//替换,修改
		Object b = map.replace("c", "4");

        // TODO 获取map集合中所有的key
        Set set = map.keySet();
        for (Object k : set) {
            System.out.println(map.get(k));
        }

		//包含
		map.containsKey("zhangsan")
            
        Collection values = map.values();// 取到其中所有的v值
        map.containsValue("1")
            
            
        // TODO 获取键值对对象
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
           System.out.println(entry.getKey() + "=" + entry.getValue());
       }

Hashtable

TODO 集合 - Map
        Hashtable
        使用:Hashtable table = new Hashtable();
        table.put(null, null);
        HashMap map = new HashMap();
        map.put(null, null);
        table.put()
                table.get()
                        table.remove()
            
         //he HashMap的区别
         TODO 1. 实现方式不一样的 : 继承父类不一样
         TODO 2. 底层结构的容量不同: HashMap(16), Hashtable(11)
         TODO 3. HashMap的K,V都可以为null, Hashtable的K, V不能是null
         TODO 4. HashMap的数据定位采用的是Hash算法,但是Hashtable采用的就是hashcode
         TODO 5. HashMap的性能较高,但是Hashtable较低

迭代器

// TODO 迭代器
Iterator<String> iterator = keys.iterator();
// hasNext方法用于判断是否存在下一条数据
while (iterator.hasNext()) {
    // 获取下一条数据
    String key = iterator.next();
    if("b".equals(key)) {
        // remove方法只能对当前数据删除,不能同时更新,用迭代器删除可以同时更新
        iterator.remove();
    }
    System.out.println(map.get(key));
}
TODO 集合 - 问题
         1. java.lang.IllegalArgumentException
            设定集合容量时,如果参数为负数,就会发生错误
        ArrayList list = new ArrayList(-1);

         2. java.util.NoSuchElementException
            从链表结构中获取数据,如果没有数据的场合,那么会发生异常
        LinkedList list = new LinkedList();
        System.out.println(list.getFirst());

         3. java.lang.IndexOutOfBoundsException
         从集合中获取数据,索引不是按照底层的数据结构设定,而是按照数据的个数决定
        ArrayList list = new ArrayList();
        list.add("zhangsan");
        list.get(3);

         4 java.util.ConcurrentModificationException
         对Map集合进行操作过程中,对数据进行了修改,就会发生错误。

Exception

TODO 集合 - Exception
         容量 :不能小于0
        ArrayList list = new ArrayList(10);

         如果访问的集合是数组,那么索引范围就是0 到数组长度-1
         如果访问的集合是List,那么索引范围就是0 到数据长度-1
        System.out.println(list.get(3));

         NoSuchElementException
        LinkedList list1 = new LinkedList();
        list1.add("a");
       System.out.println(list1.getFirst());

        HashMap一旦循环遍历时,那么如果修改数据,就会发生错误

IO

java todo 注解 java的todo_数据_02


java todo 注解 java的todo_数据_03


java todo 注解 java的todo_java todo 注解_04

TODO Java 数据 + 流(转)操作
数据从哪里来,到哪里去
TODO IO
I : Input, 输入(In)
O : Output 输出(Out)
Stream : 流转

文件流

java todo 注解 java的todo_开发语言_05

TODO Java IO - 文件流

         TODO File : 文件类型(文件,文件夹),属于java.io
         创建文件对象, 使用文件路径关联系统文件
        String filePath = "D:\\idea2022\\java-top-speed\\data";
        File file = new File(filePath); 
        System.out.println(file);

         文件对象的操作
         //TODO 判断当前文件对象是否为文件
        System.out.println(file.isFile());

         //TODO 判断当前文件对象是否为文件夹
        System.out.println(file.isDirectory());

         TODO 判断文件对象是否存在关联
        System.out.println(file.exists());

		//TODO 创建多级文件目录
          file.mkdirs();

         // TODO 创建新文件
          file.createNewFile();

		//获取文件名字
		System.out.println(file.getName());

		//最后修改时间
		System.out.println(file.lastModified());

		//当前文件绝对路径
		System.out.println(file.getAbsolutePath());

		//文件长度
		System.out.println(file.length());

		//判断是否是一个文件夹
		file.isDirectory()

Java IO - 文件复制

// TODO Java IO - 文件复制

// TODO 数据源文件对象
File srcFile = new File("D:\\idea2022\\java-top-speed\\data\\word.txt");
// TODO 数据目的地文件对象(自动生成)
File destFilt = new File("D:\\idea2022\\java-top-speed\\data\\word.txt.copy");

// TODO 文件输入流(管道对象)
FileInputStream in = null;
// TODO 文件输出流(管道对象)
FileOutputStream out = null;
        try {
                in = new FileInputStream(srcFile);
                out = new FileOutputStream(destFilt);

                // TODO 打开阀门,流转数据(输入),阀门在输入一个之后自动关闭
                int data = -1;
           
            // TODO 如果文件数据已经全部读取完毕后,那么再去读取数据,读取的结果就是-1,表示无效(结尾)
               
                正规传输写法,利用whil
            while ( (data = in.read()) != -1 ) {
                out.write(data);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if ( in != null ) {
                try {
                    in.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if ( out != null ) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

缓冲区

// TODO 缓冲输入流(管道对象)
BufferedInputStream buffIn = null;
// TODO 缓冲输出流(管道对象)
BufferedOutputStream buffOut = null;

// TODO 缓冲区(水桶)
byte[] cache = new byte[1024];

try {
    in = new FileInputStream(srcFile);
    out = new FileOutputStream(destFilt);

    buffIn = new BufferedInputStream(in);
    buffOut = new BufferedOutputStream(out);

    // TODO 打开阀门,流转数据(输入)
    //
    int data = -1;
    while ( (data = buffIn.read(cache)) != -1 ) {
        buffOut.write(cache, 0, data);
    }

} catch (IOException e) {
    throw new RuntimeException(e);
} finally {
    if ( buffIn != null ) {
        try {
            buffIn.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    if ( buffOut != null ) {
        try {
            buffOut.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

字符流

// TODO Java IO - 文件复制 - 字符串

// TODO 数据源文件对象
File srcFile = new File("D:\\idea2022\\java-top-speed\\data\\word.txt");
// TODO 数据目的地文件对象(自动生成)
File destFilt = new File("D:\\idea2022\\java-top-speed\\data\\word.txt.copy");

// TODO 字符输入流(管道对象)
BufferedReader reader = null;
// TODO 字符输出流(管道对象)
PrintWriter writer = null;
try {
    reader = new BufferedReader(new FileReader(srcFile));
    writer = new PrintWriter(destFilt);

    // TODO 打开阀门,流转数据(输入)
    // 读取文件中的一行数据(字符串)
    String line = null;

    while ( (line = reader.readLine()) != null ) {
        System.out.println(line);
        writer.println(line);
    }
    // 刷写数据:把内部缓冲区的数据全部输出到目的地
    writer.flush();

} catch (IOException e) {
    throw new RuntimeException(e);
} finally {
    if ( reader != null ) {
        try {
            reader.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    if ( writer != null ) {
        writer.close();
    }
}

序列化和反序列化

java todo 注解 java的todo_java todo 注解_06

// TODO Java IO - 文件复制 - 序列化 & 反序列化

        // TODO 数据文件对象
        File dataFile = new File("D:\\idea2022\\java-top-speed\\data\\obj.dat");

        // TODO 对象输出流(管道对象)
        ObjectOutputStream objectOut = null;
        FileOutputStream out = null;

        // TODO 对象输入流
        ObjectInputStream objectIn = null;
        FileInputStream in = null;
        try {
//            out = new FileOutputStream(dataFile);
//            objectOut = new ObjectOutputStream(out);

            // Java中只有增加了特殊的标记的类,才能再写文件中时进行序列化操作
            // 这里的标记其实就是一个接口
//            User user = new User();   //自行创建一个user类
//            objectOut.writeObject(user);
//            objectOut.flush();

            // TODO 从文件中读取数据转换成对象
            in = new FileInputStream(dataFile);
            objectIn = new ObjectInputStream(in);
            Object o = objectIn.readObject();
            System.out.println(o);

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if ( objectOut != null ) {
                try {
                    objectOut.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

Exception

// TODO Java IO
// FileNotFoundException, IOException
FileInputStream in = null;
// ClassNotFoundException, NotSerializableException
ObjectInputStream objIn = null;
ObjectOutputStream objOut = null;

try {
    in = new FileInputStream("xxx");

    in.read();
    objOut.writeObject();
    objIn.readObject();
} catch (Exception e) {
} finally {
    if ( in != null ) {
        try {
            in.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}