• java高级⑴


    1.
    之前我们学过 数组: 数组的特点: 01. 长度一旦被定义,不允许被改变 02. 在内存中开辟一连串连续的空间! 那么现在有一个需求: 让我们定义一个数组 来 保存 新闻信息!!! 问题: 01.如果定义一个数组 长度为50 今天的新闻数量只有10条! 那么有40个空间被浪费掉了! 02.今天的新闻数量只有100条! 那么无法存放多余的50条信息! 在程序的运行过程中,我们不知道需要多少个对象的时候,我们首选集合!!! 集合框架! Vector 线程安全的,但是性能低! List Set Map java中的集合框架是 jdk给我们提供好的一些列接口或者类的集合! 他们都存在于 java.util包中! public interface List<E> extends Collection<E> public interface Set<E> extends Collection<E> public interface Map<K,V> 通过观看底层代码 得知: List Set 接口都 继承了Collection接口! Collection接口中存储的都是不唯一(可以重复),无序的对象! List接口中存储的都是不唯一(可以重复),有序(插入顺序)的对象! 常用的实现类 ArrayList LinkedList Set接口中存储的都是唯一(不可以重复),无序的对象! 常用的实现类 HashSet TreeSet Map是单独的接口! Map接口存储的是一组键值对(key , value)!key是不允许重复的! 常用的实现类 HashMap TreeMap 接口不能被实例化! 所以我们刚才看到的 List Set Map 都应该有对应的实现类! 我们使用的时候肯定是使用实现类!或者使用多态! 父类引用指向子类的对象! 学数组的时候有没有工具类??? Arrays 现在集合中 也有工具类 Collections /** * ArrayList和LinkedList的区别 * ArrayList:采用数组的形式来保存数据!这些数据被放在内存中开辟连续的空间! * 每个数据的位置都有下标! * 比如说: * 现在集合长度为50! 现在想删除下标为2的元素! * 删除之后,底层还要做什么操作? * 下标为2之后的元素都要前移?? * * 现在想在下标为3的位置 新增 元素! * 下标3的元素之后的数据全部后移?? * 所以 新增,删除效率慢! * 因为是数组结构,所以遍历,查询效率高! * * LinkedList:链表式结构!存储在集合中的每个对象都存放在相互独立的空间! * 比如说: * 现在集合长度为50! * 第1个元素记录第2个元素的位置 * 第2个元素记录第3个元素的位置 * 。。。。 * 第49个元素记录第50个元素的位置 * 我们想删除第3个元素! * 只需要让 第2个元素记录第4个元素的位置! * 之后的元素有影响吗? 没有 * * 在第2个元素和第3个元素之间新增一个元素x * 这时候只需要 第2个元素 记录x的位置 * x记录第三个元素的位置 * 新增,删除效率高! * 因为没有下标,所以查询遍历的效率低! * */
    2.ArrayList
    public class ArrayTest {
    
        public static void main(String[] args) {
    
            int nums[] = new int[5];
            nums[0] = 1;
            nums[1] = 1;
            nums[2] = 1;
            nums[3] = 1;
            nums[4] = 1;
            nums[5] = 1; // ArrayIndexOutOfBoundsException
    
        }
    
    }
    ArrayList
    import java.util.ArrayList;
    
    public class ArrayListTest {
    
        public static void main(String[] args) {
            /**
             * 在程序运行过程中,不确定有多少个对象  加入到 集合中!
             * 使用集合框架!
             * 现在 我们想 新增   LinkedList
             * 现在 我们想 查询   ArrayList
             * 上述的两个类  都是  List接口的 实现类!
             * 
             * 01. ArrayList 底层是实现了一个可变长度(自动扩容)的数组!
             *     在内存中也是分配连续的空间!
             *     遍历元素和随机访问元素的时候 性能高!  因为有下标!
             */
    
            // 01创建一个ArrayList集合
            ArrayList list = new ArrayList();
            /**
             *  02. 向集合中增加元素
             *    为什么可以存放这么多数据类型
             *    因为底层就是一个Object[]数组   默认的初始长度=10
             *    Object 所有类的父类,所以可以存放任何类型!
             *  
             */
            list.add(1);
            list.add("2");
            list.add(12.5);
            list.add('5');
            list.add('1');
            list.add(null);
            list.add(7);
            list.add(8);
            list.add(9);
            list.add(10);
            list.add(11); // 自动扩充 原来长度的1.5倍
            // 03.输出集合的长度 实际使用的位置个数
            System.out.println(list.size());
            // 04. 查询集合中下标是3 的元素
            System.out.println("集合中下标是3 的元素:" + list.get(3));
            // 05. 删除下标为5的元素
            list.remove(5);
            System.out.println("删除元素之后的长度:" + list.size());
            // 06.查询集合中是否包含某个元素
            System.out.println("集合中是否包含12.5:" + list.contains(12.5));
        }
    }
    ArrayListTest

    3.LinkedList

    import java.util.LinkedList;
    
    public class LinkedListTest {
    
        public static void main(String[] args) {
            /**
             * 02.LinkedList :采用的是链表式存储结构!  插入和删除的效率高!
             *    
             *    谁能告诉我???
             *    为什么不使用 
             *   List list = new LinkedList();   父类的引用指向了子类的对象!
             *    
             *   LinkedList list=  new LinkedList();  使用这种方式!
             *   
             *    List  和 LinkedList 什么关系?
             *      001.LinkedList继承了List!
             *    List接口中有的方法LinkedList有吗?  
             *      002. 有
             *    LinkedList中有特有的方法,  List接口中有吗?  !!!!
             *      003. 没有!
             *     
             */
            // 创建集合
            LinkedList list = new LinkedList();
            // 创建新闻对象
            News news1 = new News(1, "新闻1");
            News news2 = new News(2, "新闻2");
            News news3 = new News(3, "新闻3");
            News news4 = new News(4, "新闻4");
    
            // 集合中保存新闻信息
            list.add(news1);
            list.addFirst(news2);
            list.add(news3);
            list.addFirst(news4);
    
            for (Object object : list) {
                News news = (News) object;
                System.out.println(news);
            }
    
            // 删除最后一个对象
            list.removeLast();
            System.out.println("*********************");
            for (Object object : list) {
                News news = (News) object;
                System.out.println(news);
            }
            // 查询某个元素在集合中的位置
            System.out.println("news4在集合中的位置:" + list.indexOf(news4));
    
        }
    }
    LinkedListTest

    4.Iterator

    import java.util.ArrayList;
    import java.util.Iterator;
    
    /*
     * 新闻实体类
     */
    public class News {
    
        private int id; // 新闻编号
        private String title; // 新闻标题
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public News(int id, String title) {
            super();
            this.id = id;
            this.title = title;
        }
    
        public News() {
            super();
        }
    
        @Override
        public String toString() {
            return "News [id=" + id + ", title=" + title + "]";
        }
    
        public static void main(String[] args) {
            // 创建一个集合
            ArrayList list = new ArrayList();
            // 创建新闻对象
            News news1 = new News(1, "新闻1");
            News news2 = new News(2, "新闻2");
            News news3 = new News(3, "新闻3");
            News news4 = new News(4, "新闻4");
    
            // 集合中保存新闻信息
            list.add(news1);
            list.add(news2);
            list.add(news3);
            list.add(news4);
            // list.add("aaaaaa");ClassCastException 类型转换
    
            // 01.第1种方式 遍历 for循环
            for (int i = 0; i < list.size(); i++) {
                News news = (News) list.get(i); // 必须向下转型
                System.out.println(news);
            }
            System.out.println("*****************************");
            // 02.第2种方式 遍历 for增强循环
            for (Object n : list) {
                News news = (News) n; // 必须向下转型
                System.out.println(news);
            }
            System.out.println("*****************************");
            /**
             *  03.第3种方式 遍历 iterator 迭代器循环
             *  
             *  001.hasNext() :判断我们的集合中是否还有元素
             *  002.next():获取集合中的下一个元素
             *  003.remove():删除元素
             */
            // 清空整个集合
            list.clear(); // 底层的数组 长度还是之前的长度!
            // 判断集合是否为空
            System.out.println("集合是否为空:" + list.isEmpty());
            Iterator it = list.iterator();
            while (it.hasNext()) {
                News news = (News) it.next();// 获取元素
                System.out.println(news);
            }
    
        }
    
    }
    Iterator

    5.Set

    import java.util.HashSet;
    import java.util.Set;
    
    public class SetTest {
    
        public static void main(String[] args) {
            /**
             * Set :
             *   01.存储的是唯一(不能重复) 无序的数据!
             *   02.HashSet是常用的实现类
             *   03.存放的是对象的引用
             */
    
            Set set = new HashSet();
            set.add(1);
            set.add("1");
            set.add('1');
            set.add(null);
            System.out.println(set.size()); // 输出集合的大小 4
    
            Set set2 = new HashSet();
            set2.add(1);
            set2.add(1);
            set2.add(1);
            System.out.println(set2.size()); // 输出集合的大小 1
    
            /**
             *  通过观看底层代码得知:                                        
                private transient HashMap<E,Object> map; 
                 public boolean add(E e) {               
                      return map.put(e, PRESENT)==null;  
                  }  
             01.HashSet    类中 有一个属性是 map  ,值类型是 HashMap
             02.我们在使用add(e) ,其实是调用了map.put(e,PRESENT)
                  把e当成了map的key值!
                  因为Map的key是唯一的! 所以我们的hashSet存储的也是唯一的!
             03.那么怎么知道    map中的key是唯一的呢? 看hashMap的put()  
             
               String的底层 是 char类型的数组!
               怎么比较两个值是否一致?  把char数组中的每一个元素都比较,全相等  才相等!
               
               所以hashMap在添加数据的时候
               01.先进行hash运算
               02.把计算的值当成数组中的下标
               03.判断下标指向的数组元素是否为空,如果为空 直接 添加数据
               04.如果不为空
                       依次查询entry中的所有元素
               05.判断key是否相等
                    001.e.hash == hash
                    002.(k = e.key) == key || key.equals(k)
                  如果相等  直接覆盖
               不相等 通过next的变量 将值 新增到entry!  
               
               
               
               
               HashSet 和 TreeSet的区别
               
              01. HashSet底层是哈希表实现的!
                  TreeSet底层是二叉树实现的!
              02. HashSet存放的数据是无序的!
                  TreeSet存放的数据是有序的!
              03. HashSet可以存放 null!但是只能是一个null!
                  TreeSet不可以存放null!
              04. HashSet底层是由HashMap实现! 
                  TreeSet底层是由TreeMap实现! 
              05. HashSet是线程不安全的! 单线程是安全!
                  TreeSet是线程安全的!   
               
             */
    
        }
    
    }
    set
    import java.util.HashSet;
    import java.util.Set;
    
    import org.junit.Test;
    
    public class StringTest {
    
        public static void main(String[] args) {
    
            Set set = new HashSet();
            set.add("1");
            set.add(new String("1"));
            set.add(new String("1"));
            System.out.println(set.size());
    
            // 疑问? 为什么 两次new 确是一样的
            String a = new String("1");
            String b = new String("1");
            String c = "1";
            System.out.println(a == b);
            System.out.println(a == c);
            // 内容相同的String对象 hashCode是一致的!
            System.out.println(a.hashCode() == b.hashCode());
            System.out.println(a.hashCode() == c.hashCode());
        }
    
        @Test
        public void test1() {
            String a = new String("1");
            /**
             * 01.首先在栈中开辟空间存储a
             * 02.去常量池中查询有没有 字符串1 没有就在常量池中创建字符串1
             * 03.再去堆中创建一个字符串1
             * 04.a指向堆中的字符串1
             */
            String b = "1";
            /**
             * 01.首先在栈中开辟空间存储b
             * 02.去常量池中查询有没有 字符串1   有
             * 03.b指向常量池中的字符串1
             */
            System.out.println(a == b); // false
        }
    
        @Test
        public void test2() {
            String a = "abc";
            String b = "abc";
            System.out.println(a == b); // true
            System.out.println(a == "abc"); // true
        }
    
        @Test
        public void test3() {
            String a = "abc";
            String b = "a";
            String c = "bc";
            System.out.println(a == ("a" + "bc")); // true
            /**
             * b  和  c  都是变量!!!!!!
             * 在运行期间可以改变的量!
             */
            System.out.println(a == (b + c)); // false
        }
    
        @Test
        public void test4() {
            String a = "abc";
            final String b = "a";
            final String c = "bc";
            System.out.println(a == ("a" + "bc")); // true
            /**
             * 在编译期间因为b  和  c  都是常量
             * 所以就把b+c="abc"
             */
            System.out.println(a == (b + c)); // true
        }
    }
    HashSet

    6.Map

    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import org.apache.log4j.Logger;
    import org.junit.Test;
    
    import cn.bdqn.listtest.News;
    
    public class MapTest {
    
        public static void main(String[] args) {
    
            /**
             * Map: 是一个key  value 键值对的集合!
             *       key是唯一的!
             * 
             * 存放值:
             *  put(key,value)
             *  
             * 取值
             *   get(key)    根据key获取value
             */
    
            Map map = new HashMap();
            map.put(1, "haha1");
            map.put("1", "haha2");
            map.put(new String("1"), "haha3");
            System.out.println(map.size());
        }
    
        @Test
        public void test1() {
            Map map = new HashMap();
            map.put("news1", new News(1, "新闻标题1"));
            map.put("news2", new News(2, "新闻标题2"));
            map.put("news3", new News(3, "新闻标题3"));
            /**
             * 我们想获取value的值   只能通过key
             * key是一个集合 就是set
             */
            Set keySet = map.keySet();
            for (Object o : keySet) {
                System.out.println(o); // key
            }
            /**
             * 获取所有value的集合
             */
            Collection values = map.values();
            for (Object o : values) {
                System.out.println(o); // value
            }
    
            System.out.println("****************************");
    
            // 直接使用一个循环 获取value
            for (Object key : keySet) {
                News news = (News) map.get(key); // 根据key获取value
                System.out.println(news);
            }
            System.out.println("****************************");
            Iterator it = keySet.iterator();
            while (it.hasNext()) {
                News news = (News) map.get(it.next());
                System.out.println(news);
            }
    
            System.out.println("************ EntrySet()****************");
    
            /**
             * 强烈推荐使用 EntrySet()
             * 可以在获取key的同时获取value!不需要两次查询
             */
            Iterator it1 = map.entrySet().iterator();
            while (it1.hasNext()) {
                Entry entry = (Entry) it1.next();
                System.out.println("map中的key:" + entry.getKey());
                System.out.println("map中的value:" + entry.getValue());
            }
        }
    
        Logger log = Logger.getLogger(MapTest.class);
    
        @Test
        public void test2() {
            Map map = new HashMap();
            for (int i = 1; i <= 200000; i++) {
                map.put(i, "" + i);
            }
            System.out.println("map的大小:" + map.size());
    
            // 获取当前的毫秒数 从1970年1月1日到现在的毫秒
            long start = System.currentTimeMillis();
            Set keySet = map.keySet();
            for (Object key : keySet) {
                System.out.println(map.get(key));
            }
            long end = System.currentTimeMillis();
            log.debug("使用for循环的用时:" + (end - start));
    
            start = System.currentTimeMillis();
            Iterator iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry entry = (Entry) iterator.next();
                System.out.println(entry.getValue());
            }
            end = System.currentTimeMillis();
            log.debug("使用Iterator循环的用时:" + (end - start));
        }
    
        /***
         * 
         *  HashMap 和  HashTable 的区别
         *   01.HashMap    线程不安全 但是性能高
         *      HashTable  线程   安全 但是性能低
         *   02.HashMap 底层是哈希表实现的,每一个元素一个key -value键值对!
         *        key和value都可以为null!
         *      HashTable的key和value都不可以为null!
         *   03.历史版本不同
         *      HashMap    1.2
         *      HashTable  1.0
         */
    }
    MapTest

    7.泛型

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import org.junit.Test;
    
    import cn.bdqn.listtest.News;
    
    public class MyTest {
    
        @Test
        public void test01() {
            ArrayList list = new ArrayList();
            // list中可以存放什么类型! Object 所有类型
            list.add(1);
            list.add("1");
            list.add(new Date());
            /**
             *  我们怎么去遍历这些类型的数据
             *  01.集合中的数据不是相同类型
             *  02.不能按照一种方式去遍历
             */
    
            Set set = new HashSet();
            set.add(1);
            set.add("1");
            set.add(new Date());
    
            Map map = new HashMap();
            map.put(1, "1");
            map.put("1", "haha");
            map.put("2", new Date());
    
            /**
             * 上面三个 集合 
             * 01.因为我们没有在创建集合的同时 规定集合中可以存放什么类型的数据
             * 02.所以集合中可以存放Object类型的数据
             * 03.导致后续操作很麻烦
             * 04.如果我们想获取集合中的某个元素,需要使用get()
             * 05.但是get()返回值是 object类型
             * 06.需要向下转型,转换成指定的类型,之后才能操作!
             * 
             * 
             * 有没有一种方式,
             * 01.可以在创建集合的时候,规定集合中只能存放什么类型
             * 02.能不能在get()不进行向下转型!!!
             * 
             * 能!
             * 使用泛型!
             * 泛型集合:  创建集合的时候,规定集合中存放数据的类型!
             * 
             */
    
        }
    
        /**
         *  使用泛型集合   方便+安全
         *  <> 就是集合中指定的元素类型!
         *  
         *  泛型集合中 不允许 存放基本数据类型的元素!
         *  如果想存放基本数据类型!
         *  必须使用基本数据类型对应的 包装类
         *  
         *  java中有8种基本数据类型,使用ctrl+鼠标左键   点不进去! 说明不是类
         *   
         *  那就有8个对应的包装类!
         *  byte    Byte
         *  short   Short
         *  int     Integer        
         *  long    Long
         *  float   Float
         *  double  Double
         *  
         *  boolean  Boolean
         *  char     Character
         *  
         */
        @Test
        public void test02() {
            ArrayList<String> list = new ArrayList<String>();
            // 说明list集合中只能存放String类型的数据
            // list.add(new Date()); 编译报错
            ArrayList<News> list2 = new ArrayList<News>();
            // list2集合中 只能存放 News 对象!
            ArrayList<Double> list3 = new ArrayList<Double>();
            list3.add(2.0);
    
            double a = 2;
            // Double b = 2; 编译报错
        }
    
        @Test
        public void test03() {
            /**
             * 创建了一个map泛型集合!
             * 集合的key只能是String类型
             * value只能是News类型!
             * 
             * map.put(1,"1"); 错误
             * map.put("1","1"); 错误
             * map.put("1",new News());
             */
            Map<String, News> map = new HashMap<>();
            News news1 = new News(1, "新闻1");
            News news2 = new News(2, "新闻2");
            News news3 = new News(3, "新闻3");
            map.put("a", news1);
            map.put("b", news2);
            map.put("c", news3);
    
            // 遍历出来所有的新闻信息
            Iterator<Entry<String, News>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, News> entry = iterator.next();
                // System.out.println(entry.getKey()); 获取所有的key
                News news = entry.getValue(); // 获取所有的value
                System.out.println(news);
            }
    
        }
    }
    泛型
  • 相关阅读:
    《剑指offer》面试题7:旋转数组的最小数字
    eclipse ------ TODO、FIXME、XXX 等任务标记
    RT-Thread ------ waitqueue
    RT-Thread ------ 设备注册
    ubuntu 安装 glibc
    openwrt上面移植MQTT代码
    MH5000-31模组无法识别SIM卡
    "Hello osmdroid World"手机GPS轨迹数据
    地质数据下载
    绘图软件Surfer绘制等高线
  • 原文地址:https://www.cnblogs.com/wwlw/p/7490464.html
Copyright © 2020-2023  润新知