zoukankan      html  css  js  c++  java
  • Java基础01

    string

    1. 构造方法每创建一次对象,都会在堆内存中开辟不同的对象空间。所以,每new一次,都是不同的对象。
    2. 直接定义的字符串内容会存储到堆内存中的常量池里。字符串内容如果相同,则直接共享使用。

    字符串的比较

    1. ==号如果比较的是基本数据类型,比较的是具体的值,==号如果比较的是引用数据类型,比较的是对象的地址值
    2. 比较字符串内容是否相同,使用equals()方法

    字符串的比较

    1. 记住俩个重要方法:length(),charAt(); 用for循环实现

    StringBuilder

    1. 每拼接一个字符串,都会产生新的字符串对象。这种操作会比较浪费内存空间!StringBuilder来解决这个问题
    2. Stringbuilder是可变的字符串对象
    public static String arryToString(int[] array){
    2        StringBuilder stringBuilder = new StringBuilder();
    3
    4        stringBuilder.append("[");
    5
    6        for (int i = 0; i < array.length; i++) {
    7            if(i==array.length-1){
    8                stringBuilder.append(array[i]);
    9            }else {
    10                stringBuilder.append(array[i]).append(",");
    11            }
    12        }
    13
    14        stringBuilder.append("]");
    15
    16        String s = stringBuilder.toString();
    17        return s;
    18    }

    String&StringBuffer&StringBuilder

    • String:不可变字符序列,底层使用char[]存储。
    • StringBuffer:可变的字符序列,线程安全的,效率低,底层使用char[]存储
    • StringBuilder:可变字符串序列,线程不安全的,效率高,底层使用char[]存储。

    Collection

    • JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List 。
    • 用多态的方式创建collection对象。(具体实现类ArrayList)
    • collection用迭代器遍历,迭代器是一个内部类。
    • 迭代器创建的时候指向的不是第一个元素,而是第一个元素的上方空元素。判断是否有下一个元素是相对于当前迭代器指向的地方而言的。
    • 集合存储的是引用数据类型。不能存储基本数据类型。

    List

    • 有序:存储和取出的是顺序一致。
    • 可重复:存储的元素可以重复。
    • 并发修改异常 ConcurrentModificationException
     1//并发修改异常 ConcurrentModificationException
    2        List<String> list = new ArrayList<String>();
    3        list.add("hello");
    4        list.add("word");
    5
    6        Iterator<String> iterator = list.iterator();
    7
    8        while (iterator.hasNext()){
    9            String s = iterator.next();
    10            if(s.equals("word")){
    11                list.add("JavaSE");
    12            }
    13        }
    14
    15        System.out.println(list);
    16    }
    17
    18
    19Exception in thread "main" java.util.ConcurrentModificationException
    20    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
    21    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
    22    at com.Gao.ArrayList.List_Demo.main(List_Demo.java:22)
    • 分析:源码分析之后可以看到迭代器遍历过程中,丢改了集合的长度,导致实际修改次数和预期修改次数不一致,从而抛出了异常
    • 解决方案: 在if之后家break跳出循环,防止执行checkForComodification();或者用for循环的方式。
    • 数组是查询快,增删慢的数据结构,链表是查询慢,增删快的数据结构。

    list的常用子类ArrayList&linkedList

    • ArrayList底层是数组
    • linkedList底层是链表
    • 3种遍历方式 1.迭代器 2.for循环遍历 3. for增强遍历
    linkedList集合特有功能
    • 因为是linkedList特有功能,所以不能用多态的当时创建(父类不能调用子类的方法)
    1. addFirst()
    2. getFirst()
    3. removeFirst()

    set集合

    HashSet

    • 不包含重复元素
    • HashSet该类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代顺序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素。
    • 底层数据结构是哈希表

    哈希值

    • JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
    • Object类中HashCode()方法可以获取对象的哈希值。
    • 同一个对象的哈希值是一样的。
    • 默认情况下不同对象的哈希值是不同的。(重写hashCode方法可以实现让不同字符串的哈希值相同)
    保证元素唯一性的源码分析
     1public boolean add(E e) {
    2                return map.put(e, PRESENT)==null;
    3            }
    4
    5             static final int hash(Object key) {
    6                    int h;
    7                    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    8                }
    9
    10             public V put(K key, V value) {
    11                    return putVal(hash(key), key, value, false, true);
    12                }
    13                // hash值和元素的hashCode()相关
    14                final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
    15                                   boolean evict) {
    16                        Node<K,V>[] tab; Node<K,V> p; int n, i;
    17                        //如果哈希表未初始化,就对其进行初始化
    18                        if ((tab = table) == null || (n = tab.length) == 0)
    19                            n = (tab = resize()).length;
    20
    21                            //根据对象的哈希值计算对象的存储位置,如果该位置没有元素就存储元素
    22                        if ((p = tab[i = (n - 1) & hash]) == null)
    23                            tab[i] = newNode(hash, key, value, null);
    24                        else {
    25                            Node<K,V> e; K k;
    26                            /*
    27                            存入的元素和以前的元素比较哈希值
    28                            如果哈希值不同,会继续向下执行,把元素添加进去,
    29                            如果哈希值相同,会调用equals方法
    30                              返回true,元素重复不存储
    31                              返回false 则存储
    32
    33                            */
    34
    35                            if (p.hash == hash &&
    36                                ((k = p.key) == key || (key != null && key.equals(k))))
    37                                e = p;
    38                            else if (p instanceof TreeNode)
    39                                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
    40                            else {
    41                                for (int binCount = 0; ; ++binCount) {
    42                                    if ((e = p.next) == null) {
    43                                        p.next = newNode(hash, key, value, null);
    44                                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
    45                                            treeifyBin(tab, hash);
    46                                        break;
    47                                    }
    48                                    if (e.hash == hash &&
    49                                        ((k = e.key) == key || (key != null && key.equals(k))))
    50                                        break;
    51                                    p = e;
    52                                }
    53                            }
    54                            if (e != null) { // existing mapping for key
    55                                V oldValue = e.value;
    56                                if (!onlyIfAbsent || oldValue == null)
    57                                    e.value = value;
    58                                afterNodeAccess(e);
    59                                return oldValue;
    60                            }
    61                        }
    62                        ++modCount;
    63                        if (++size > threshold)
    64                            resize();
    65                        afterNodeInsertion(evict);
    66                        return null;
    67                    }
    哈希表保证元素唯一性实现方法
    1. 计算出带存入对象的哈希值
    2. 将哈希值对象对16求余。
    3. 分别存入0-15的地址
    4. 若地址一样,比较哈希值和内容,如果都不一样,则用链表插入该元素的后面。

    LinkedHashSet

    1. 底层实现是哈希表和链表
    2. 由链表保证元素顺序,存入和取出的顺序一致。
    3. 由哈希表保证元素的唯一

    TreeSet

    1. 元素有序(不是存取顺序),按照一定的规则进行排序,具体排序方法取决于构造方法。
    2. 没带索引,不能用普通for方法遍历,需要用增强的for方法。
    3. 由于是set集合所以元素没有重复的
    4. 用treeset存储自定义对象时,该对象的类要实现Comparable<>(自然排序)接口。
    @Override
    2    public int compareTo(Student o) {
    3        int num = this.age-o.age;
    4        num = (num == 0) ? this.name.compareTo(o.name) : num;
    5        return (num);
    6    }
    1. 比较器comparator的使用
    1 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
    2            @Override
    3            public int compare(Student o1, Student o2) {
    4                int num = o1.getAge()-o2.getAge();
    5                num = (num==0)?o1.getName().compareTo(o2.getName()):num;
    6                return num;
    7            }
    8        });
    1. 比较器排序就是让集合构造方法接受比较器的实现类对象,重写compare方法。
    2. 不重复的随机数
    1  Random random = new Random();
    2        TreeSet<Integer> set = new TreeSet<Integer>();
    3        while (set.size()<10){
    4            set.add(random.nextInt(20)+1);
    5        }
    6
    7        for (Integer integer : set) {
    8            System.out.println(integer);
    9        }

    泛型

    1. 提供了编译时类型安全检测机制,本质时将类型参数化。
    2. 优点:将运行时期的异常提前到了编译期间,避免了强制类型转换
    3. 指定一种类型的格式,这个类型可以看成时形参
    4. 将来具体调用的时候给定的类型可以看成时实参,并且实参的类型只能是引用类型。

    泛型方法

    public <T> void show(T t){
    2        System.out.println(t);
    3    }

    类型通配符

    为了表示各种泛型List的父类,可以使用类型通配符

    • 类型通配符:
      List: 表示元素类型未知的List,它的元素可以匹配任何的类型
    • 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
      如果说我们不希望List是任何泛型ist的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
    • 类型通配符 上限:
      List:它表示的类型是Number或者其子类型
      除了可以指定类型通配符的上限,我们也可以指定类型通配符的下限
    • 类型通配符下限:
      List:它表示的类型是Number或者其父类型

    Map集合

    1. 将键映射到值的对象。 Map不能包含重复的键; 每个键可以映射到最多一个值。
    2. HashMap<>(),的key和value的类型,不能是基本数据类型,需要时引用类型,所以要是基本类型的包装类,int-->Integer,char---->Character等等。

    俩种遍历方式

     1//遍历map方式1
    2        Set<String> keySet = map.keySet();
    3        for (String s : keySet) {
    4            System.out.println(s+":"+map.get(s));
    5        }
    6
    7        //遍历map方式2
    8        Set<Map.Entry<String, String>> entrySet = map.entrySet();
    9        for (Map.Entry<String, String> mapEntry : entrySet) {
    10            //mapEntry是每一个map对象
    11            System.out.println(mapEntry.getKey()+"-->"+mapEntry.getValue());
    12        }
  • 相关阅读:
    sql推断时间
    COCOFrame
    第41周一
    第40周日
    第40周六
    第40周五
    第40周四
    第40周三国庆
    第40周二晚
    第40周二
  • 原文地址:https://www.cnblogs.com/g414056667/p/14675364.html
Copyright © 2011-2022 走看看