• java入门了解07


    1.集合:

            1.1相比数组的优势:

                   a.可以存储任意类型的对象数据,数组只能存储一种类型的变量

                   b.集合的长度会发生变化,数组不会

            1.2集合概述

    ----|Collection: 单列集合

    -----------|List: 有存储顺序, 可重复

    -----------|ArrayList: 数组实现, 查找快, 增删慢

                                   由于是数组实现, 在增和删的时候会牵扯到数组

                                   增容, 以及拷贝元素. 所以慢。数组是可以直接

                                   按索引查找, 所以查找时较快

    -----------|LinkedList: 链表实现, 增删快, 查找慢

                                   由于链表实现, 增加时只要让前一个元素记住自

                                   己就可以, 删除时让前一个元素记住后一个元

                                   素, 后一个元素记住前一个元素. 这样的增删效

                                   率较高但查询时需要一个一个的遍历, 所以效率

                                   较低

                                   同样实现了Queue接口,就能用到类似于队列的方法了

                                   1:栈 (1.6) : 主要是用于实现堆栈数据结构的存储方式。
                                                   先进后出
                                                    push()
                                                    pop()
                                   2:队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
                                                   先进先出
                                                    offer()
                                                    poll()

    -----------|Vector: 和ArrayList原理相同, 但线程安全, 效率略低

                                和ArrayList实现方式相同, 但考虑了线程安全问

                                题, 所以效率略低

    -----------|Set: 无存储顺序, 不可重复

    -----------|HashSet

    -----------|TreeSet

    -----------|LinkedHashSet

    -----------| Map: 键值对

    -----------|HashMap

    -----------|TreeMap

    -----------|HashTable

    -----------|LinkedHashMap

    为什么出现这么多集合容器,因为每一个容器对数据的存储方式不同,这种存储方式称之为数据结构(data structure)

    注意 集合和数组中存放的都是对象的引用。

    有序: 集合的有序不是指自然顺序,而是指添加进去的顺序与元素出来的顺序是一致的。

            1.3什么时候用什么类型的集合

    Collection

    我们需要保存若干个对象的时候使用集合。

    List

    如果我们需要保留存储顺序, 并且保留重复元素, 使用List.

    如果查询较多, 那么使用ArrayList

    如果存取较多, 那么使用LinkedList

    如果需要线程安全, 那么使用Vector

    Set

    如果我们不需要保留存储顺序, 并且需要去掉重复元素, 使用Set.

    如果我们需要将元素排序, 那么使用TreeSet

    如果我们不需要排序, 使用HashSet, HashSet比

    TreeSet效率高.

    如果我们需要保留存储顺序, 又要过滤重复元素, 那么使用LinkedHashSet

            1.5Collection接口中的共性方法:   

                   a.  增加
                      add(E e)  添加成功返回true,添加 失败返回false.
                      addAll(Collection c)  把一个集合 的元素添加到另外一个集合中去。
                   b. 删除
                      clear()
                      remove(Object o)
                      removeAll(Collection  c)
                      retainAll(Collection  c)
                  c. 查看
                      size()

                  d.  判断
                      isEmpty()
                      contains(Object o)
                      containsAll(Collection<?> c)
                  e. 迭代
                      toArray()
                      iterator()

            2.List接口中特有方法:

                  操作的方法都含有index
                  a.添加
                     add(int index, E element)
                     addAll(int index, Collection<? extends E> c)
                  b.获取:
                     get(int index)
                     indexOf(Object o)
                     lastIndexOf(Object o)
                     subList(int fromIndex, int toIndex)
                 c.修改:
                     set(int index, E element)

                 d.迭代
                     listIterator()

    增加

    public static void main(String[] args) {
            Collection list = new ArrayList();
            // 增加:add() 将指定对象存储到容器中
            list.add("计算机网络");
            list.add("现代操作系统");
            list.add("java编程思想");
            System.out.println(list);
            // [计算机网络, 现代操作系统, java编程思想]
            
            // 增加2 将list容器元素添加到list2容器中
            Collection list2 = new ArrayList();
            list2.add("java核心技术");
            list2.addAll(list);
            list2.add("java语言程序设计");
            System.out.println(list2);
            // [java核心技术, 计算机网络, 现代操作系统, java编程思想, java语言程序设计]
        }
    View Code

    3.List集合迭代器listIterator

            我的理解:这就是List集合的一个指针集合对象,可以对集合通过指针方式对集合操作;

            定义:提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator)

            特有的方法:hasPrevious()

                             Previous();

                             next();add(E e);set(E e)

            代码:

     
    public class Demo3 {
        
        public static void main(String[] args) {
            List list = new ArrayList();
            list.add("狗娃");
            list.add("狗剩");
            list.add("铁蛋");
            list.add("美美");
            
            ListIterator it = list.listIterator(); //返回的是一个List接口中特有的迭代器
            /*System.out.println("有上一个元素吗?"+ it.hasPrevious());
            System.out.println("获取上一个元素:"+it.previous());
            it.next();
            System.out.println("获取上一个元素:"+ it.previous());
            
            
            while(it.hasNext()){
                it.next();
            }
            
            while(it.hasPrevious()){
                System.out.println("元素:"+ it.previous());
            }
            
            
            it.next();
            it.next();
            it.add("张三");
            */
            it.next();
            it.next();
            it.set("张三");
            
            
            System.out.println("集合的元素:"+ list);
            
            
        }
    
    }
    View Code

    使用三种方式遍历集合的元素.
    第一种: 使用get方法遍历。
    第二种: 使用迭代器正序遍历。
    第三种: 使用迭代器逆序遍历。

    public class Demo4 {
        
        public static void main(String[] args) {
            List list = new ArrayList();
            list.add("张三");
            list.add("李四");
            list.add("王五");
            
            System.out.println("======get方法遍历=======");
            for(int i = 0 ; i<list.size() ; i++){
                System.out.print(list.get(i)+",");
            }
            
            System.out.println("
    ======使用迭代器正序遍历==========");
            ListIterator it = list.listIterator();    //获取到迭代器
            while(it.hasNext()){
                System.out.print(it.next()+",");
            }
            
            System.out.println("
    ======使用迭代器逆序遍历==========");
            while(it.hasPrevious()){
                System.out.print(it.previous()+",");
            }
            
            
        }
    
    }
    View Code

    4.

    4.线程间通讯(生产者消费者)

               (一)一个线程完成自己的任务,要通知另一个线程去完成另一个任务

               (二)wait(): 等待 如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify方法才能唤醒。

                       notify(): 唤醒 唤醒线程池等待线程其中的一个。
                       notifyAll() : 唤醒线程池所有等待 线程。


                       wait与notify方法要注意的事项:
                            1. wait方法与notify方法是属于Object对象 的。
                            2. wait方法与notify方法必须要在同步代码块或者是同步函数中才能 使用。
                            3. wait方法与notify方法必需要由锁对象调用。

               (三)例子:生产者消费者

                        很好的一段代码,解析已经很清楚了关系生产者消费者,synchronized,nodify,wait的使用,线程安全的解决

    package cn.itcast.thread;
    /*
     线程通讯: 一个线程完成了自己的任务时,要通知另外一个线程去完成另外一个任务.
     
    生产者与消费者
    
    
    wait():  等待   如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify方法才能唤醒。
    notify(): 唤醒    唤醒线程池等待线程其中的一个。
    notifyAll() : 唤醒线程池所有等待 线程。
    
    
    wait与notify方法要注意的事项:
        1. wait方法与notify方法是属于Object对象 的。
        2. wait方法与notify方法必须要在同步代码块或者是同步函数中才能 使用。
        3. wait方法与notify方法必需要由锁对象调用。
        
    问题一:出现了线程安全问题。 价格错乱了...
     
     */
    
    //产品类
    class Product{
        
        String name;  //名字
        
        double price;  //价格
        
        boolean flag = false; //产品是否生产完毕的标识,默认情况是没有生产完成。
        
    }
    
    //生产者
    class Producer extends Thread{
        
        Product  p ;      //产品
        
        public Producer(Product p) {
            this.p  = p ;
        }
        
        
        
        @Override
        public void run() {
            int i = 0 ; 
            while(true){
             synchronized (p) {
                if(p.flag==false){
                     if(i%2==0){
                         p.name = "苹果";
                         p.price = 6.5;
                     }else{
                         p.name="香蕉";
                         p.price = 2.0;
                     }
                     System.out.println("生产者生产出了:"+ p.name+" 价格是:"+ p.price);
                     p.flag = true;
                     i++;
                     p.notifyAll(); //唤醒消费者去消费
                }else{
                    //已经生产 完毕,等待消费者先去消费
                    try {
                        p.wait();   //生产者等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                 
            }    
          }    
        }
    }
    
    
    //消费者
    class Customer extends Thread{
        
        Product p; 
        
        public  Customer(Product p) {
            this.p = p;
        }
        
        
        @Override
        public void run() {
            while(true){
                synchronized (p) {    
                    if(p.flag==true){  //产品已经生产完毕
                        System.out.println("消费者消费了"+p.name+" 价格:"+ p.price);
                        p.flag = false; 
                        p.notifyAll(); // 唤醒生产者去生产
                    }else{
                        //产品还没有生产,应该 等待生产者先生产。
                        try {
                            p.wait(); //消费者也等待了...
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }    
        }
    }
    
    public class Demo5 {
        
        public static void main(String[] args) {
            Product p = new Product();  //产品
            //创建生产对象
            Producer producer = new Producer(p);
            //创建消费者
            Customer customer = new Customer(p);
            //调用start方法开启线程
            producer.start();
            customer.start();
            
            
        }
        
    }
    View Code
  • 相关阅读:
    linux 压力测试工具之ab
    docker save load export import的区别
    手把手教你打造高效的 Kubernetes 命令行终端
    K8S 中的容器编排和应用编排
    linux mount一个目录到另外一个目录
    linux sed命令详解
    各种安全证书间的关系及相关操作
    Linux Shell/Bash wildcard通配符、元字符、转义符使用
    vim打开多个文件、同时显示多个文件、在文件之间切换
    吉他演奏中的速度与节拍
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/day07.html
走看看 - 开发者的网上家园