1.集合家族体系

Collection是父接口

List和Set是子接口

Map也是一个接口

面试题:说出Collection与Collections的区别?

Collection是一个单例集合的根接口,Collections是操作集合对象的工具类

 

2. List接口

数据取出是有序的,但存储空间有些有序,有些无序

2.1 ArrayList

ArrayList 有序的 有下标 线程不安全 允许为null

  • 初始为一个空的Object数组

  • 当我们第一次添加元素的时候 将数组的长度赋为10

  • 当集合长度不够用的时候,扩容是原来的1.5倍

  • 查询快 但添加、删除慢

 

import java.util.Date;
/**
 *  新闻信息类
 *  标题
 *  作者
 *  日期
 *  内容  
 * @author asus
 *
 */
public class News {
    private String title;
    private String author;
    private Date date;
    private String content;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public News() {
    }
    public News(String title, String author, Date date, String content) {
        this.title = title;
        this.author = author;
        this.date = date;
        this.content = content;
    }
    @Override
    public String toString() {
        return "News [title=" + title + ", author=" + author + ", date=" + date + ", content=" + content + "]";
    }
    
}
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
 *  ArrayList 有序的 有下标 线程不安全 允许为null
 *  1.初始为一个空的Object数组
 *  2.当我们第一次添加元素的时候将 数组的长度赋值为10
 *  3.当集合长度不够用的时候,扩容是原来的1.5倍
 *  4.查询快 添加 删除 慢 
 * @author asus
 */
public class TestNews {
    public static void main(String[] args) {
        // 使用ArrayList集合存放新闻信息
        ArrayList<News> list = new ArrayList<News>();
        Date date = new Date(2020,8,1);
        News n1 = new News("周末竟然和女朋友做这事,全世界都震惊了", "赵四", new Date(), "在家做饭");
        News n2 = new News("周末竟然和女朋友做这事,全世界都震惊了", "广坤", new Date(), "在家洗衣服");
        News n3 = new News("周末竟然和女朋友做这事,全世界都震惊了", "小宝", date, "在家看电视");
            
        list.add(n1);
        list.add(n2);
        list.add(n3);
        
        System.out.println("集合原长度" + list.size());
        list.remove(0);
        list.remove(n2);
        System.out.println("删除第二个元素之后集合长度" + list.size());
        News n4 = new News("周末竟然和女朋友做这事,全世界都震惊了", "小沈阳", date, "在家跳舞");
        News modifyNews = list.set(1, n4);
        
        System.out.println("修改之前的元素内容" + modifyNews);
        System.out.println("修改之后的元素内容" + list.get(1));
        System.out.println("清空集合之前" + list.isEmpty());
        
        System.out.println("===========================");
        // 遍历集合
        // for循环
        // 第一种方式
        for(int i = 0; i < list.size() ; i ++) {
            System.out.println(list.get(i));
        }
        
        System.out.println("===========================");
        
        // 第二种方式 增强for循环
        // 格式 for(Type name : list){
        // 
        // }
        for(News ns : list) {
            System.out.println(ns);
        }
        System.out.println("===========================");
        
        // 第三种方式 迭代器的方式 
        // 迭代器必须使用while循环类遍历 因为 没有下标
        Iterator<News> it = list.iterator();
        while(it.hasNext()) {
            News next = it.next();
            System.out.println(next);
        }
            
        list.clear();
        System.out.println("清空集合之后" + list.isEmpty());
    }
}

遍历ArrayList方法

  • 普通for循环遍历

  • 增强for循环遍历(foreach)

  • 迭代器遍历

总结:

三种遍历方式的优缺点:

  1. for循环是基于下标查找的 所以我们可以做一些基于下标的操作

  2. 如果不需要对下标的操作,推荐使用增强for循环或者迭代器

  3. 不要在增强for循环以及迭代器中删除或者添加数据,将会报并发访问异常

  4. 增强for循环内部依然是迭代实现的,是JDK1.5新添加的内容,迭代器是JDK1.2有的

or:

      普通for循环 基于下标遍历 可以做一些基于下标的操作

      增强for循环 不能操作下标 效率高 底层实现还是迭代器

      迭代器 不能操作下标 效率高

import java.util.ArrayList;
import java.util.Iterator;
/**
 *  三种遍历方式的优缺点:
 *  1.for循环是基于下标查找的 所以我们可以做一些基于下标的操作 
 *  2.如果不需要对下标的操作 推荐使用增强for循环或者迭代器 
 *  3.不要在增加for循环或者迭代器中删除或者添加数据 将会报并发访问异常
 * @author asus
 */
public class TestForeach {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<Integer>(); 
        for (int i = 0; i < 200000; i++) {
            list1.add(i);
        }
        
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < list1.size(); i++) {
            if(i == 1) {
                list1.remove(i);
            }
            System.out.println(list1.get(i));
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通循环耗时" + (endTime - startTime)); // 1700 毫秒
            
        startTime = System.currentTimeMillis();
        // 增强for循环 是JDK1.5 才有的 内部依然使用迭代器实现
        for(Integer i : list1) {
            
            System.out.println(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("增强循环耗时" + (endTime - startTime)); // 1439毫秒
            
        startTime = System.currentTimeMillis();
        // 迭代器  1.2 
        Iterator<Integer> it = list1.iterator();
        
        while(it.hasNext()) {
            list1.remove(it.next());
            System.out.println(it.next());
        }
        endTime = System.currentTimeMillis();
        System.out.println("迭代器耗时" + (endTime - startTime)); // 600毫秒
    }
}

ArrayList源代码实现

1.ArrayList无参构造

2.Array初始化数组长度(第一次添加元素时)

 

3.ArrayList确保有足够的空间,扩容1.5倍

 

4.ArrayList扩容,并且赋值数组

 

5.ArrayList删除元素

总结:ArrayList特点是查询快,添加和删除慢,因为涉及到移动元素,所以我们在一些查询占比高于删除和添加的场景可以使用。比如,电商系统

2.2 Vector

Vector类有和ArrayList相同的API,但是是线程安全的

面试题:

ArrayList和Vector的区别?

相同点:ArrayList与Vector底层都是使用了Object数组实现的。

  1. Vector是JDK1.0就有的,ArrayList是JDK1.2才有的

  2. Vector无参构造直接给数组长度赋值为10,而ArrayList是第一次添加内容的时候才给数组长度赋值为10

  3. Vector扩容是原来的2倍,ArrayList是原来的1.5倍

  4. Vector是线程安全的,ArrayList是线程不安全的

遍历方式与ArrayList一致

​import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
​
public class TestVector {
    public static void main(String[] args) {
        // 此类与ArrayList有相同的API 先存在的  线程安全的 
        Vector v1 = new Vector(); // 无参构造直接初始化为10
        v1.add(20);
        v1.add("赵四");
        v1.add(23.0);
        
        // 热插拔 
        List<Object> v2 = new Vector<Object>();
        v2.add(20D);
        v2.add(21D);
        v2.add(22D);
        v2.add(23D);
        v2.add(24D);
        
        System.out.println("原集合长度" + v2.size());
        System.out.println("删除的元素是" + v2.remove(0));
        System.out.println("删除一个元素以后" + v2.size());
        System.out.println("第一个元素" + v2.get(0));
        v2.set(0, 66D);
        System.out.println("第一个元素" + v2.get(0));
        
        System.out.println("清空之前是否为空" + v2.isEmpty());
            System.out.println("================================");
        
        for (int i = 0; i < v2.size(); i++) {
            System.out.println(v2.get(i));
        }
            System.out.println("================================");
        for (Object object : v2) {
            System.out.println(object);
        }
            System.out.println("================================");
        
        Iterator<Object> it = v2.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        
        v2.clear();
        System.out.println("清空之后是否为空" +v2.isEmpty());
        
    }
}

2.3 LinkedList

特点:

无序的(存储空间)、可以为null,线程不安全,基于双向链表实现

除了提供与ArrayList方法名称相同的方法之外,还提供了链表数据结构特有的一些用于操作头部和尾部的一些方法

增删快、查询慢

使用场景:仓库管理系统或者图书管理系统,涉及到频繁修改数据的

ArrayList中remove需指定下标,LinkedList不指定是默认删除第一个

import java.util.LinkedList;
/**
 *  LinkedList 也是List接口的实现类 也是Deque接口的实现类
 *  LinkedList既是一个线性表也是一个队列(双向链表)
 *  除了提供和ArrayList方法名称相同的方法之外 还提供了链表数据结构特有的一些
 *  单独用于操作 头部 和 尾部的一些方法     
 * @author asus
 */
public class Test1 {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        // 无序的 是指空间不连续 
        list.add("a");
        list.add(20);
        list.addFirst("B");
        list.addLast("C");
        list.add(1, "中文");
        
        System.out.println("集合长度" + list.size());
        System.out.println("第一个元素是" + list.getFirst());
        System.out.println("第二个元素" + list.get(1));
        list.getLast();
        list.removeFirst();
        list.removeLast();
        list.remove();
        
        for (Object object : list) {
            System.out.print(object + "\t");
        }
        System.out.println();
        System.out.println("删除第一个元素以后,集合长度" + list.size());
        
        list.set(1, "A");
        
        for (Object object : list) {
            System.out.print(object + "\t");
        }
        System.out.println();   
        System.out.println("集合是否为空" + list.isEmpty());  
        list.clear();       
        System.out.println("集合是否为空" + list.isEmpty());
    
    }
}

遍历LinkedList

三种方式:

  1. 普通for循环

  2. 增强for循环

  3. 迭代器

注意:不可使用普通for循环遍历LinkedList,太慢了!!!

疑问:Iterator方法返回的是一个接口类型,为什么接口又可以调用方法使用呢? 答: 多态的使用,灵活。Iterator实际上返回的是Iterator接口的实现类对象。

import java.util.Iterator;
import java.util.LinkedList;
​
public class Test3 {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<Integer>();
        for (int i = 0; i < 20; i++) {
            list.addFirst(i);
        }
        System.out.println("=================");
        
        // 1 普通for循环 
        for(int i = 0; i < list.size(); i ++) {
            System.out.println(list.get(i));
        }
        
        // 2 增强for循环
        for(Integer i : list) {
            System.out.println(i);
        }
        
        // 3 迭代器
        Iterator<Integer> it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

LinkedList源码解读 

1.add方法

2.addFirst方法

3.addLast方法

4.addLast方法内部实现

5.getFirst方法

6.getLast方法

7.LinkedList查找元素方法

8.removeFir实现t内部 

9.remove方法内部实现 

10. 每一个元素都是一个Node

 

3. Map接口

3.1 HashMap

特点:无序、线程不安全 、允许键和值为null,键不能重复

ArrayList是基于数组 有下标 查询快,但因涉及到移动元素、增删慢

LinkedList基于双向链表 无下标 所以查询慢 但也是因为通过指针建立联系,所以增删快

问:能不能将以上两个集合 结合到一起呢?

答:可以 HashMap就是 几乎实现了将两者结合到一起

JDK 1.7 数组 + 单向链表

JDK1.8 数组 + 单向链表 + 红黑树 当单向的链表的长度大于8时,转换为红黑树 提高查询效率

扩容是2倍

效率:增删改查都快知识理想状态,实际应用中会有影响,只是相对的提高了增删改查的效率,缺点是占用空间大

import java.util.ArrayList;
import java.util.HashMap;
​
public class Test1 {
    public static void main(String[] args) {
        // 定义一个集合 存储成对的信息 
        ArrayList<String> list = new ArrayList<String>();
        list.add("US美国");
        list.add("JP日本");
        list.add("CN中国");
        
        HashMap<String,String> map =new HashMap<String,String>();
        map.put("US", "美国");
        map.put("RU", "俄罗斯");
        map.put("CN", "中国");
        map.put("JP", "小日本");
        System.out.println(map.size());
        // map集合 键和值 都允许为 null 键不能重复 如果重复 那么将覆盖值
        map.put("JP", "日本");
        System.out.println(map.size());
        
        System.out.println(map.get("JP"));
        System.out.println("删除的元素value是" + map.remove("JP"));
        
        System.out.println(map.isEmpty());
        map.clear();
        System.out.println(map.isEmpty());
​
    }
}

遍历方式

  1. 获取所有key,根据key获取值    Set<String> set = map.keySet();

  2. 获取所有的值     Collection<String> values = map.values();

  3. 获取Set<Entry<?,?>>获取所有的整条数据的集合   Set<Entry<String, String>> entrySet = map.entrySet();

  4. 获取整条数据的集合迭代器map.entrySet().iterator();


import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
/**
 *  HashMap 集合特点
 *  无序
 *  线程不安全
 *  允许键和值为null 键不能重复
 *  效率
 *  增删改查
 *  ArrayList是基于数组 有下标 所以查询快  同样也是因为有下标 涉及到移动元素 所以增删慢
 *  LinkedList 基于双向链表 没有下标 所以查询慢 同样也是因为没有下标 增删快
 *  能不能将以上两个集合 结合到一起呢?
 *  可以的 HashMap就是 几乎实现了将两者结合到一起
 *  JDK 1.7  数组 + 单向链表 
 *  JDK 1.8 数组 + 单向链表 + 红黑树  当单向的链表的长度大于8时候 转换为红黑树 提高查询效率
 *  扩容 2倍 
 * @author asus
 *
 */
public class Test2 {
    public static void main(String[] args) {
        // keySet()  返回所有的key集合 set集合 
        HashMap<String,String> map =new HashMap<String,String>();
        map.put("US", "美国");
        map.put("RU", "俄罗斯");
        map.put("CN", "中国");
        map.put("JP", "小日本");
        
        Set<String> set = map.keySet();
        for (String key : set) {
            System.out.print(key + "\t" + map.get(key));
            System.out.println();
        }
        System.out.println("=================");
        
        // 获取所有的value  values()
        Collection<String> values = map.values();
        for (String value : values) {
            System.out.println(value);
        }
        System.out.println("==================");
        
        Set<Entry<String, String>> entrySet = map.entrySet();
        for(Entry en : entrySet) {
            System.out.println(en.toString());
        }
        System.out.println("==================");
        // 使用迭代器
        Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
        while(iterator.hasNext()) {
            Entry<String, String> next = iterator.next();
            System.out.println(next.getKey() + "===" + next.getValue());
        }
    
    }
}

HashMap数据结构

3.2 Hashtable(注意大小写)

面试题:

HashMap和Hashtable的区别?

此类提供与Hashtable相同的实现,但是是线程安全的,默认容量是11,扩容是两倍+1,键和值都不允许为null,无序的

import java.util.Hashtable;

/**
 * 	Hashtable 
 * 	无序
 * 	线程安全的
 * 	键和值都不允许null
 * @author asus
 *
 */
public class Test3 {
	public static void main(String[] args) {
		Hashtable<Integer,String> table = new Hashtable<Integer,String>();
		table.put(1, "A");
		table.put(2, "B");
		table.put(3, "C");
			
	}
}

3.3 Properties(Hashtable子类)

Properties:属性

是Hashtable子类,也是线程安全的不要使用put或者putAll方法添加内容(使用setProperties()),因为此类只用于存放键和值都是String的内容

import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
​
/**
 *  Properties 类 
 *  Hashtable子类
 *  线程安全
 *  键和值都为String
 *  不要使用put或者putAll方法添加内容
 * @author asus
 */
public class TestProperties {
    public static void main(String[] args) {
//      Properties properties1 = System.getProperties();
//      properties1.list(System.out);           
//      properties.put(20, 20.0); // 不要使用put方法来添加内容 
//      properties.get(20);
        
        Properties properties2 = new Properties();
        properties2.setProperty("CN", "中国");
        properties2.setProperty("US", "美国");
        properties2.setProperty("JP", "日本");
        properties2.setProperty("KR", "韩国");
        properties2.setProperty("RU", "俄罗斯");
        
        properties2.list(System.out);
                
        System.out.println(properties2.size());             System.out.println(properties2.get("CN"));
        
        Set<Entry<Object, Object>> set = properties2.entrySet();
        System.out.println("-- listing properties --");
        for(Entry<Object, Object> entry : set) {
            System.out.println(entry);
        }
                System.out.println("===============================");
        
        Set<Object> keys = properties2.keySet();
        for(Object key : keys) {
            System.out.println(properties2.get(key));
        }
        System.out.println("===============================");
        
    }
}

3.4 TreeMap(Comparator接口)

TreeMap是可以保证顺序的Map集合,要求键必须可以排序,也就是必须实现Comparable接口,重写CompareTo()方法

import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
/**
 *  Tree 树 
 *  TreeMap是有顺序的Map集合 所存放的数据Key值必须可以比较 而且是升序的顺序
 *  我们自定义的对象必须实现Comparable接口 重写CompareTo方法
 * @author asus
 *
 */
public class TestTreeMapAndTreeSet {
    public static void main(String[] args) {
        TreeMap<String,String> map  =new TreeMap<String,String>();
        map.put("A","赵四");
        map.put("a","广坤");
        map.put("h","大拿");
        map.put("B","小宝");
        
        map.remove("A");
        
        for(Entry<String,String> entry : map.entrySet()) {
            System.out.println(entry);
        }
        map.clear();
        map.size();
        map.isEmpty();      
        System.out.println("=================================");
        SortedMap<Person,String> map1 = new TreeMap<Person,String>();
        map1.put(new Person("赵四",20), "A");
        map1.put(new Person("广坤",21), "F");
        map1.put(new Person("小宝",22), "c");
        map1.put(new Person("大拿",23), "B");
        
        System.out.println(map1.size());
        for(Entry<Person,String> entry : map1.entrySet()) {
            System.out.println(entry);
        }
                System.out.println("=================================");        
    }
}

4.Set接口

4.1HashSet(底层HahMap,不保证存储顺序)

HashSet底层是一个HashMap,因为HashMap键不能重复的特点,所以可以使用HashMap维护一个我们创建的HashSet

特点:

  • 无序

  • 不能重复、不允许添加两个对象 A.equals(B)为true,且A和B的hashCode相等

  • 线程不安全

  • 可以为null

HashSet去重复是根据对象的hashCode和equals方法比较,都为true,则认为是同一个对象

import java.util.HashSet;
import java.util.Iterator;
/**
 *  HashSet
 *  无序
 *  不能重复 不允许添加两个对象 A和B  A.equals(B) 
 *  线程不安全
 *  可以为null
 *  HashSet去重复是根据对象的hashCode和equals方法比较 都为true 则认为是同一个对象
 * @author asus
 *
 */
public class TestHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<String>();
        set.add("A");
        set.add("hello");
        set.add("20");
        set.add("中国");
        System.out.println("第二次添加A" + set.add("A"));
        
        System.out.println(set.size());
        for(String str : set) {
            System.out.println(str);
        }
                System.out.println("=======================");
        Iterator<String> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("=======================");
            
        System.out.println(set.remove("A"));
        System.out.println(set.size());
        
        set.clear(); // 清空集合
        System.out.println(set.isEmpty());
    }
}

4.2 LinkedHashSet(可保证存储顺序)

HashSet的子类,基于链表的HashSet,可以保证数据的顺序,顺序就是插入的顺序

import java.util.Iterator;
import java.util.LinkedHashSet;
/**
 *  HashSet是无序的 不能保证顺序
 *  如果需要保证顺序 并且元素不能重复  可以使用LinkedHashSet
 *  LinkedHashSet是基于链表的 HashSet  可以保证元素的顺序  插入顺序
 * @author asus
 */
public class TestLinkedHashSet {
        public static void main(String[] args) {
            LinkedHashSet<String> set = new LinkedHashSet<String>();
            set.add("A");
            set.add("hello");
            set.add("中国");
            set.add("千锋");
            set.add("666");
            System.out.println("=======================");
            for(String str : set) {
                System.out.println(str);
            }
            System.out.println("=======================");
            Iterator<String> it = set.iterator();
            while(it.hasNext()) {
                System.out.println(it.next());
            }
            System.out.println("=======================");
            set.remove("A");
            
            System.out.println(set.size());
            set.clear();
            
            System.out.println("清空集合以后" + set.isEmpty());           
        }
}

4.3 TreeSet(底层TreeMap,Comparator接口)

TreeSet是可以保证顺序的Set集合,与LinkedHashSet不同,TreeSet是按照比较定义的顺序,LinkedHashSet是按照插入的顺序,TreeSet底层要求保存的内容必须可以排序,也就是必须实现Comparable接口,重写CompareTo方法

import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
/**
 *  Tree 树 
 *  TreeMap是有顺序的Map集合 所存放的数据Key值必须可以比较 而且是升序的顺序
 *  我们自定义的对象必须实现Comparable接口 重写CompareTo方法
 * @author asus
 */
public class TestTreeMapAndTreeSet {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<String>();
        set.add("你好");
        set.add("A");
        set.add("B");
        set.add("hello");
        
        for(String str : set) {
            System.out.println(str);
        }
​
        TreeSet<Worker> set1 = new TreeSet<Worker>();
        
        set1.add(new Worker());
        set1.add(new Worker());
        set1.add(new Worker());
        set1.add(new Worker());
        System.out.println(set1.size());
    }
}
package com.qfedu.test2;
​
public class Worker implements Comparable<Worker>{
​
    @Override
    public int compareTo(Worker o) {
        return 0; // 此处没有定义比较规则 同一返回0 那么将只能添加一个Worker对象 因为所有的Worker对象相比都相等
    }
}

5.泛型

作用:相当于一个占位符,可以规范数据类型 ,有点类似于Object的作用,但是注意不能类型转换

适用场景:

接口,类、抽象类、形参、返回值

泛型可以使任何的字符,一般常用的:

T: Type

E: Element

K: Key

V: Value

package com.qfedu.test2;
​
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
 *  泛型 <T>
 *  作用:相当于一个  占位  符 可以规范数据类型  有点类似于Object的作用 但是注意不能类型转换 
 *  使用场景:
 *  接口 类
 *  方法形参 返回值  
 *  占位符 T Type   E Element  K key  V value   
 * @author asus
 */
public class TestGeneric {
    public static void main(String[] args) {
        AImpl1 ai = new AImpl1();
        ai.m1("hello wolrd");
        
        AImpl2 ai2 = new AImpl2();
        ai2.m1(20);
        B<String> b = new B<String>();
        b.m1();
        B<Integer> b1 = new B<Integer>();
        b1.m2(1);
        E.m1("String");
    }
}
​
class C<K,V>{
    public V m1(K k) {
        return null;
    }   
}
​
class E{
    public static <T> void m1(T t) {
        System.out.println(t);
    }
}
​
class B<T>{
    public T m1() {
        return null;
    }
    
    public void m2(T t) {
        System.out.println(t);
    }
    
}
​
interface A<T>{
    void m1(T sb);
    
    void m2(Object obj);
    T m3();
}
​
class AImpl1 implements A<String>{
    @Override
    public void m1(String sb) {
        
    }
    @Override
    public void m2(Object obj) {
        
    }
    @Override
    public String m3() {
        return null;
    }   
}
​
class AImpl2 implements A<Integer>{
​
    @Override
    public void m1(Integer i) {
        System.out.println(i);
    }
​
    @Override
    public void m2(Object obj) {
        
    }
​
    @Override
    public Integer m3() {
        return null;
    }
}
​
class Animal{
    
}
​
class Dog extends Animal{
    
}
​
class Cat extends Animal{
    
}
​
class Test{
    /**
     *  ? extends Animal 表示泛型可以是Animal或者Animal的子类
     * @param set
     */
    public void m1(Set<? extends Animal> set) {
        
    }
    
    public void m2(List<? super Dog> list) {
        
    }
    
//  public void m3(List<Dog extends ?> list) {
//      
//  }
    
    public static void main(String[] args) {
        Test test = new Test();
        test.m1(new HashSet<Dog>());
        test.m1(new HashSet<Cat>());
        test.m1(new HashSet<Animal>());
//      test.m1(new HashSet<String>());
        test.m2(new ArrayList<Dog>());
        test.m2(new ArrayList<Animal>());
//      test.m2(new ArrayList<Cat>());
        test.m2(new ArrayList<Object>());
    }
}

6.Collections

Collections是集合工具类

Collection是集合父接口

常用方法:

排序 sort() 适用于List实现类的类型

求最大值 max

求最小值 min

二分查找 binarySearch 必须先排序才能保证本方法返回正确结果 适用于List实现类的类型

/**
 * Collections是集合工具类
 * Collection是集合父接口
 * 排序  sort
 * 求最大值 max
 * 求最小值 min
 * 二分查找  binarySearch  必须先排序才能保证本方法返回正确结果
 * @author asus
 */
public class TestCollections {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(20);
        list.add(40);
        list.add(10);
        list.add(5);
        //使用时需对集合排序 ,,适用于list接口下的
        System.out.println("5在集合中的位置:" + Collections.binarySearch(list, 5));
        Collections.sort(list);
        System.out.println("5在集合中的位置:" + Collections.binarySearch(list, 5));
    
        System.out.println("排序以后");
        for(Integer integer : list){
            System.out.println(integer);
        }
        
        System.out.println("集合中的最大元素:" + Collections.max(list));
        System.out.println("集合中的最小元素:" + Collections.min(list));
​
        List<String> strList = new ArrayList<String>();
        strList.add("A");
        strList.add("w");
        strList.add("G");
        strList.add("j");
        strList.add("a");
        
        Collections.sort(strList);
        
        for(String string: strList){
            System.out.println(string);
        }
    }
}

每日问题1

1.ArrayList实现了哪个接口?

2.ArrayList集合的数据结构是什么,特点是什么?底层数据结构,是否有序,是否安全,是 否允许为null

3.ArrayList初始容量是多少,扩容是多少?

4.ArrayList和Vector的区别

5.StringBuffer和StringBuilder的区别

6.三种遍历ArrayList的方式是什么,有什么区别?

7.是否可以在增强for或者迭代器中增加或者删除元素

8.ArrayList增删改查的方法是什么

每日问题2

1.JDK8HashMap数据结构

2.HashMap和Hashtable的区别

3.HashMap是哪个接口的实现类,初始容量是多少,增长多少,负载因子是多少,什么含 义

4.遍历HashMap的三种方式

5.JDK提供的数组排序为哪个类的哪个方法

6.ArrayList和LinkedList区别

每日问题3

1.HashSet去重复的原理是什么,HashSet和HashMap的区别是什么?

2.TreeMap和TreeSet特点,关系

2.ArrayList、LInkedList、Vector三个类的关系

3.Collection和Collections的区别,如何实现集合排序,对排序的类型有什么要求

4.如果需要对一个泛型为自定义类型的集合进行排序,需要做什么操作

5.可以保证顺序的set集合是哪些类?插入顺序和排序顺序

6.Properties应该使用的添加数据的方法是什么?为什么不能使用 put或者putAll

7.Set <? extends Animal>和Set<? super Animal>分别表示什么含义

解答1

1.ArrayList实现了哪个接口?

    List

2.ArrayList集合的数据结构是什么,特点是什么?底层数据结构,是否有序,是否安全,是 否允许为null

    数组

    有序 线程不安全 null 查询快,增删慢

3.ArrayList初始容量是多少,扩容是多少?

    0,当我们第一次添加元素,赋值长度为10,扩容1.5倍

4.ArrayList和Vector的区别

    1.Vector是JDK1.0就有的,ArrayList是JDK1.2才有的

    2.Vector无参构造直接给数组长度赋值为10,而ArrayList是第一次添加内容 的时候才给数组长度赋值为10

    3.Vector扩容是原来的两倍,ArrayList是原来的1.5倍

    4.Vector是线程安全的,ArrayList是线程不安全的

5.StringBuffer和StringBuilder的区别

    StringBuffer线程安全的 JDK1.0

    StringBuilder非线程安全的 JDK1.5

6.三种遍历ArrayList的方式是什么,有什么区别?

    普通for循环 基于下标遍历 可以做一些基于下标的操作

    增强for循环 不能操作下标 效率高 底层实现还是迭代器

    迭代器 不能操作下标 效率高

7.是否可以在增强for或者迭代器中增加或者删除元素

    不能,会抛出并发访问异常

8.ArrayList增删改查的方法是什么

    add remove set get

解答2:

1.JDK8HashMap数据结构

     数组+ 单向链表 + 红黑树 当链表的长度大于8 将转换为红黑树 提高查询效率

2.HashMap和Hashtable的区别

    HashMap 1.2 16 2倍 线程不安全

    Hashtable 1.0 11 2倍 + 1 线程安全

3.HashMap是哪个接口的实现类,初始容量是多少,增长多少,负载因子是多少,什么含 义

    Map接口 初始 16 扩容2倍 负载因子0.75F

4.遍历HashMap的三种方式

    keySet()方法获取所有的key

    获取所有的值, values()

    entrySet()获取所有的条目项,数据的集合Set> Iterator> it = entrySet().iterator();

5.JDK提供的数组排序为哪个类的哪个方法

    Arrays.sort()

6.ArrayList和LinkedList区别

    ArrayList是有序的 线程不安全 基于数组 需要扩容 扩容1.5倍

    LinkedList 无序的 线程不安全 基于链表 不需要扩容 拥有List接口方法之外独有的操作 头和尾的方法

解答3:

1.HashSet去重复的原理是什么,HashSet和HashMap的区别是什么?

    HashSet去重复是根据对象的hashCode和equals方法比较 都为true 则认 为是同一个对象

    HashSet中维护的是一个HashMap的键

2.TreeMap和TreeSet特点,关系

    两个类都是有序的,TreeSet中维护的是TreeMap的键

2.ArrayList、LInkedList、Vector三个类的关系

    都实现与List接口

    ArrayList和Vector都是数组的结构

    ArrayList是线程不安全的

    Vector是线程安全的

    LinkedList是双向链表 增删快 查询慢 线程不安全的

3.Collection和Collections的区别,如何实现集合排序,对排序的类型有什么要求

    Collection是集合父接口 Collections是集合工具类

    Collections.sort() 排序的类型必须实现Comparable接口 重写compareTo方法

4.如果需要对一个泛型为自定义类型的集合进行排序,需要做什么操作

    排序的类型必须实现Comparable接口 重写compareTo方法

5.可以保证顺序的set集合是哪些类?

    插入顺序和排序顺序 LinkedHashSet和TreeSet

6.Properties应该使用的添加数据的方法是什么?为什么不能使用 put或者putAll

    setProperty()

    因为Properties集合键和值都是String类型的 而使用put或者putAll可以插入其他的类 型

7.Set <? extends Animal>和Set<? super Animal>.分别表示什么含义

    Set <? extends Animal>表示泛型的类型可以是Animal或者Animal的子类

     Set<? super Animal>表示泛型的类型可以是Animal或者Animal的父类

posted on 2020-08-15 10:40  zitian246  阅读(150)  评论(0编辑  收藏  举报