Java复习,Java知识点以及Java面试题(四)
集合框架:
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
Collection 集合的顶层接口
Collection 方法概述:
添加 boolean add(Object obj): 添加一个元素
boolean addAll(Collection c): 添加一个集合的元素
删除 void clear(): 移除所有元素
boolean remove(Object o)移除一个元素
boolean removeAll(Collection c)移除一个集合的元素 只要有一个元素被移除了,就返回true
判断 boolean contains(Object o): 判断集合中是否包含指定的元素
boolean containsAll(Collection c):判断集合中是否包含指定的集合元素 只有包含所有元素,才叫包含
boolean isEmpty(): 判断集合是否为空
获取 Iterator<E>iterator() 迭代器,集合的专用遍历方式:获取元素并移动到下一个位置: Object next();判断是否有下一个元素:boolean hasNext()
长度 int size(): 元素个数
交集 boolean retainAll(Collection c) 两个集合AB,AB做交集,最终结果保存在A中,B不变,返回值表示A是否发生过改变
把集合转换为数组 Object[] toArray()
迭代器:遍历集合的一种方式
依赖于集合而存在
迭代器原理:为什么不定位为一个类,而是一个接口?
Java中集合类的数据结构不同,存储方式和遍历方式不同,所以没有定义迭代器类。无论在哪种集合都应该具备获取元素的操作,并辅助于判断功能,把这个两个功能提取出来,并不提供具体实现,这种方式就是接口。 实现类在真正的具体的子类中,以内部类的方式体现的。
List:有序,可重复
添加:void add(int index, Object element):在指定位置添加元素
获取:Object get(int index): 获取指定位置的元素
列表迭代器:ListIterator listIterator(): List集合特有的迭代器
删除功能:Object remove(int index):根据索引删除元素
修改功能:Object set(set index, Object element):根据索引修改元素,并返回被修改的元素
遍历:size()和get()方法结合使用
使用迭代器
增强for
ListIterator的特有方法:
Object previous(): 获取上一个元素
boolean hasPrevious(): 判断是否有上一个元素
List的子类:
ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高
Vector:底层数据结构是数组,查询快,增删慢。线程安全,效率低
LinkedList:底层数据结构是链表,查询慢,增删快。线程不安全,效率高
Vector:
添加:public void addElement(Object obj)
获取:public Object elementAt(int index)
public Enumeration elements()
Enumeration接口的方法:boolean hasMoreElements()
Object nextElement()
LinkedList:
添加:public void addFirst(Object e)
public void addLast(Object e)
获取:public Object getFirst()
public Object getLast()
删除:public Object removeFirst()
public Object removeLast()
泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊类型,参数化类型,把类型当作参数一样传递。
例如:ArrayList<String> array = new ArrayList<String>();
作用:把运行时期的问题提前到了编译期间
避免了强制类型的转换
泛型推断:ArrayList<String> array = new ArrayList<>();
早期的Object类型可以接受任意的对象类型,但是在实际使用中,会有类型转换的问题,也就存在着隐患,所以Java提供了泛型来解决这个安全问题。
泛型类:
把泛型定义在类上,格式:public class 类名 <泛型类型1,.....>,注意泛型类型必须是引用类型
泛型方法:
把泛型定义在方法上,格式:public <泛型类型> 返回类型 方法名(泛型类型....)
泛型接口:
把泛型定义在接口上,格式:public interface 接口名<泛型类型1....>
泛型通配符:
?:表示任意类型
?extands E:向下限型,E及其子类
?super E: 向上限型,E及其父类
增强for:简化了数组和集合的遍历,但是增强for的目标不能为null
格式: for(元素数据类型 变量:数组或者Collection集合){
使用变量即可,该变量就是元素
}
增强for其实是用来替代迭代器的
静态导入:
格式:import static 包名...类名.方法名
可以直接导入到方法的级别
注意:方法必须是静态的,注意多个同名的静态方法
可变参数:定义方法的时候不知道该定义多少个参数
格式:修饰符 返回值类型 方法名 (数据类型... 变量名){ }
注意:这里的变量其实是一个数组,如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
ArrayList集合的toString()方法源码:
1 代码: 2 Collection c = new ArrayList(); 3 c.add("hello"); 4 c.add("world"); 5 c.add("java"); 6 7 System.out.println(c); 8 9 为什么c输出的不是地址值呢? 10 A:Collection c = new ArrayList(); 11 这是多态,所以输出c的toString()方法,其实是输出ArrayList的toString() 12 13 B:看ArrayList的toString() 14 而我们在ArrayList里面却没有发现toString()。 15 以后遇到这种情况,也不要担心,你认为有,它却没有,就应该去它父亲里面看看。 16 17 【C:toString()的方法源码】 18 19 public String toString() { 20 Iterator<E> it = iterator(); //集合本身调用迭代器方法,得到集合迭代器 21 if (! it.hasNext()) 22 return "[]"; 23 24 StringBuilder sb = new StringBuilder(); 25 sb.append('['); 26 for (;;) { 27 E e = it.next(); //e=hello,world,java 28 sb.append(e == this ? "(this Collection)" : e); 29 if (! it.hasNext()) 30 //[hello, world, java] 31 return sb.append(']').toString(); 32 sb.append(',').append(' '); 33 } 34 }
Set:不包含重复元素,无序
HashSet保证元素唯一性的源码:
通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。
思路步骤:首先比较哈希值, 如果相同,继续走,比较地址值或者走equals(), 如果不同,就直接添加到集合中
LinkedHashSet:
底层数据结构由哈希表和链表组成,哈希表保证元素的唯一性,链表保证元素有序
TreeSet:排序和唯一 底层是红黑树
能够对元素按照某种规则进行排序
排序有两种方式:自然排序(无参构造):元素具备比较性 让元素所属的类实现自然排序接口Comparable,比较器排序(带参构造):集合具备比较性 让集合的构造方法接收一个比较器接口的子类对象Comparetor
唯一性根据比较的返回是否是0来决定
Map集合
将键映射到值的对象,一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map集合的数据结构只针对键有效,跟值无关。
Map方法概述:
1:添加:V put(K key, V value ): 添加元素,如果键是第一次存储,就直接存储返回null;若不是第一次,就修改value,返回以前的值。
2:删除: void clear(): 移除所有的键值对元素
V remove(Object key): 根据键删除键值对元素,并把值返回
3:判断: boolean containsKey(Object key): 判断集合是否包含指定的键
boolean containsValue(Object value): 判断集合是否包含指定的值
boolean isEmpty(): 判断集合是否为空
4:获取:Set<Map.Entry<K,V>> entrySet(): 返回的是键值对对象的集合
V get (Object key): 根据键获取值
Set<K> keySet(): 获取集合中所有键的集合
Collection<V> values(): 获取集合中所有值的集合
5:长度:int size(): 返回集合中的键值对的对数
HashMap
LinkedHashMap 是Map接口的哈希表和链表实现,具有可预知的迭代顺序
由哈希表保证键的唯一性,由链表保证键的有序(存储和取出的顺序一致)
TreeMap
是基于红黑树的Map接口实现。
Hashtable和HashMap的区别
HashMap:线程不安全,效率高。允许null键和null值
Hashtable:线程安全,效率低,不允许null键和null值
Collections工具类
针对集合操作的工具类
Colllection和Collections的区别:
Collection是单列集合的顶层接口,有子接口List和Set
Collections是针对集合操作的工具类,有对集合进行排序和二分查找的方法
方法
public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。
public static <T> int binarySearch(List<?> list,T key):二分查找
public static <T> T max(Collection<?> coll):最大值
public static void reverse(List<?> list):反转
public static void shuffle(List<?> list):随机置换