List集合
该添加方法是在集合的指定位置添加元素,指定位置原有元素的位置向后挪了一位(即下标加1):
List.add(集合下标,添加元素);(集合实现类:ArrayList())
该添加方法是将另外一个集合(参数)的元素添加到集合的结尾处:
List.addAll(Collection c );
List集合的底层实现:
List集合的子类包括:ArrayList
底层使用的是:数组
注意:实现数组长度可变,指的是重新创建一个新的数组,长度大于旧数组
LinkedList
底层使用:链表结构
特点:每一个元素,前半部分是具体的值,后半部分是地址值
List集合的特点:
元素可重复,不唯一,有序(添加顺序/索引顺序/先后顺序)
集合只能存储对象或引用数据类型,基本数据类型不允许存放在集合当中。
当集合添加基本数据类型的时候,会自动装箱(将基本数据类型转换成引用数据类型)。
引用数据类型可以使用“==”和equals()方法比较,使用equals()方法比较集合元素是否重复。
List集合输出的三种方式:
标准for循环,增强for循环
以及迭代器(重点):(集合中的标准输出方法)
System.out.println("==============迭代器输出===================");
//获取迭代器----List集合当中存在一个方法----iterator() 返回值类型是Iterator
Iterator<Integer> iter=list.iterator();
//借助while循环语句
while(iter.hasNext()){
System.out.print(iter.next()+"\t");
}
迭代器常用的三个方法:
判断是否有下一个元素:hashNext() 获取当前元素:next() 移出当前元素:remove()
泛型的设置:
位置:可以在类上以及接口设置泛型,泛型的形式<T>
T:输入具体的数据类型,则此时的T就代表什么类型,特点:对集合和接口等增加了约束。
泛型的应用:可以应用在方法上,类以及接口上。
理解面向接口编程:
接口的作用:添加约束,本质是一个契约,需要遵守:如果你是。。。则必须能。。。的思想
Collection集合:
Collection的定义:
此集合是集合框架当中层次结构的根集合。
Collection表示一组对象,这些对象也称为collection的元素。
public interface Collection<E> extends Iterable<E>
虽然Collection集合作为跟集合存在,但是他也有一个父几口,就是Iterable(迭代器)接口。
特点:
不唯一:说明集合元素可以重复,并且打印输出集合元素的时候,也会跟着输出
无序:不是按照添加元素,也不是按照自然顺序(升序/排序)
Collection和它的子集合List和Set集合:
(凡是list集合以及set集合的实现类,都是collection集合的实现类)
List:子集合大量的扩充父集合当中的方法,子集合存在很多父集合当中没有的方法。
eg:List.add(int index,E e);list.remove(int index);
Set:set集合基本上没有扩充父集合当中的方法
Collection当中的一些常用方法:
添加元素的方法:add(E e) addAll(Collection c);
删除元素的方法:remove(Object obj)
修改元素的方法:Collection集合没有,不过list集合中存在set()方法
获取元素的方法:Collection集合没有,不过list集合中存在get()方法
获取迭代器的方法:Iteration()方法
获取集合容量大小:size()方法
清除集合元素的方法:clear()方法
ArrayList集合:(重写List)
List集合的底层使用的是长度可变的数组。
实现长度可变的数组--此处的数组并不是指的同一个数组,而是创建新数组,新数组的长度是就数组的2倍,把旧数组的元素重新赋值给新数组。
空数组,表现形式:
int[] arr = null; 代表的是在栈内存当中声明数组,没有在堆内存当中开辟空间
int[] arr = {}; 代表的是数组元素个数为0;
根据jdk当中的ArrayList集合,初始容量是10个,所以在自定义ArrayList类的时候,写空参构造方法,需要指定容量,其实就是调用另外一个有参构造方法
LinkedList集合:
LinkedList集合的定义:
使用连接列表实现list集合接口的类,叫链表类。(此实现不是同步的)
底层使用的是链表结构:
优点:插入删除元素效率比较高
缺点:遍历和随机访问元素效率低下
常用方法:
添加元素:
add(E e)
add(int index E e)
addFirst(E e)
addLast(E e)
删除的方法:
remove(E e)
Remove(int index,E e)
removeFirstr()
removeLast()
获取的方法:
get(int index)
getFirst()
getLast()
修改的方法:
public E set(int index, E element)
获取但不异常此列表的头(第一个元素)
public E peek() public E element()
获取并移除此列表的头(第一个元素)
public E poll()
Set<E>集合:
定义:
一个不包含重复元素的集合,更确切的说,set不包含内容相同的元素,并且最多包含一个null元素,就是说也可以存null
特点:无序且唯一
常用的一些子类有:
HashSet:采用Hashtable哈希表存储结构,优点:添加查询删除速度快,缺点:无序(☆)
LinkedHashSet:采用哈希表存储结构,同时使用链表维护次序(有序:添加顺序)
TreeSet:采用二叉树(红黑树)的存储结构
优点:有序 查询速度比list快(按照内容查询)
缺点:查询速度没有hashset快
Set集合的底层原理有哪些结构完成:
第一种:使用哈希表---HashSet
第二种:使用二叉树--TreeSet
链表结构+哈希表接口----->保证元素的有序和唯一,此处的有序指的是添加顺序。
二叉树结构-----> 保证元素的有序和唯一,此处的有序指的是自然顺序。
自然顺序: 如果是数值型,则从小到大;如果是字母,则按照从a--z的顺序;如果是汉字,则按照Unicode编码表中的顺序进行排序
List集合的特点:要求元素不唯一而且有序!
Set集合的常用方法:
增加元素
add(E e )
特点: 没有在指定位置进行添加的方法 List集合当中存在一个
删除元素
remove(Object o); 按照元素的内容进行删除
注意: 没有按照索引位置进行删除的方法,List集合当中存在一个
修改的方法,Set集合没有
获取元素的方法----get()方法,Set集合也没有
注意: 推论,既然没有get方法,那么能够使用标准for循环进行遍历Set集合!
判断是否为空 --- isEmpty()
获取迭代器 --- iterator()
注意: 推论 凡事属于Collection集合的子集合,都具备迭代器输出的功能
获取集合容量大小/获取集合元素个数---size()方法
集合转换数组的方法
Object[] toArray()
该方法的参数是个数组(你想转换成啥类型的数组,长度为set集合的长度),这样下边那个转换数组的方法返回的数组就是你声明的这个数组,实际上就是提前给这个方法声明个容器
T[] toArray(T[] t);
注意:1. T代表的是Type单词的缩写,指的是数据类型
- 在进行传参的过程当中,必须是一个具体的,在堆内存当中开辟空间的数组。
特性:(HashSet为例)
在添加某些对象时,可以添加匿名对象,好处: 不用再单独创建对象了,直接是以实参的方式进行传递。(“new Test();”这就是一个匿名对象,但是,在Java一般不这么使用,因为没有意义,因为这样写完后,由于没有对该对象进行引用,所以马上就被内存回收了,所以没有实际意义)
在创建集合时,对集合进行遍历输出,推荐使用迭代器输出,原因: 迭代器专门为集合而生!
凡事属于Collection集合的子集合,都具有迭代器的功能/方法
关键问题: 在编写迭代器时,泛型的类型要和集合的泛型保持一致!
对于重复元素,Set集合要保持元素的唯一性,但是我发现,在使用Student类充当泛型时,重复元素可以打印输出。
原因:Student类没有重写equals()方法和hashCode()方法,对于JDK存在的类,例如Integer Double String等类,
已经重写了equals()方法和hashCode()方法。
LinkedHashSet子类的特点
采用哈希表存储结构,同时使用链表维护次序(有序(添加顺序))
常用的方法----基本上都是继承而来的方法
添加的方法
add(E e) --- 继承Set接口当中的方法
删除的方法
remove(Object obj)
迭代输出的方法
iterator()
TreeSet集合:
TreeSet的定义:
此类是以二叉树的存储结构,按照子软顺序进行排序的一个集合子类!
TreeSet集合的特点
效率问题: TreeSet执行效率要高于List集合,但是低于HashSet集合
有序而且元素唯一: 有序 (自然顺序)
常用方法
添加的方法
add(E e)
删除的方法
remove(Object o);
通过元素的索引值进行获取元素---get(int index)
听过元素的索引值进行修改元素---set(int index)
清除集合当中所有的元素----clear()
比较的方法---comparator()
注意: 此方法的返回值类型是Comparator接口,它是一个内部比较器
外部比较器----Comparable
判断是否包含指定的元素---- contains(Object o)
返回Set集合当中的第一个元素----public E first();
返回Set集合当中的最后一个元素----public E last()
内部比较器----Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
返回结果,分别返回不同的数据:
如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数
发现:此接口,只存在一个抽象方法,此方法的定义如下:
public int comparaTo(Object obj); 比较此对象与指定对象的顺序。
分析: 此接口为什么叫内部比较器?
原因: 1.从字面意思上理解,肯定还有一个外部比较器---Comparator<T>
2.在集合当中,有的集合对元素要进行排序----特指的是Set集合当中,TreeSet要求按照自然排序
在去使用此集合的时候,泛型类型都自动的实现了此接口,例如: Integer String Double类等
自定义类来充当集合的泛型,如果对其进行排序(内部自动的排序),则此类也要实现Comparable接口,否则会出现ClassCastException
MAP集合:
获取所有的value值,把他们存放大Collection集合当中
public Collection<v> values();
直接获取键和值,而不是分开获取的方法
public Set<Map.Entry<K,V>> entrySet()
注意: 发现此方法,返回的是Set集合
发现: 如果把Map集合当中所有的元素放到Set集合当中,发现不妥,也就是说不能把包含键值对的元素放到Set集合当中,因为Set集合只能存储单值元素
解决:Set集合是否可以编写泛型----可以的
Map集合当中有一个嵌套的子集合---Entry<K,V>
换句话说: 把Set集合的泛型,改为Entry<k,v>
格式: Set<String> Set<Integer> ---- 发现:String Integer都是属于类
Set<Entry<k,v>> -----发现:Entry<K,V>是接口形式存在
结论: 泛型的类型,可以是引用数据类型,其中包括: 类和接口
遍历map集合的两种方式:
第一种: 单独的获取所有的key 和 value
第二种: 使用entrySet()方法,把Map集合转换成Set集合,再通过迭代器输出
LinkedHashMap类:
底层使用到了链表+哈希表。
特点: 解决了Map集合存储数据以及遍历集合时,无序的状态 --- 按照添加元素/先后顺序。
注:在编写泛型类型的时候,只允许编写引用数据类型的数据,不能写基本数据类型。
此处JVM是不会吧int进行包装,变成包装类。
TreeMap:有序(自然顺序)
TreeMap类底层使用了二叉树(红黑树)结构,会自动的对产品进行排序。
使用TreeMap集合,是有序的,而且这个有序指的是自然顺序---从小到大的顺序
String类型,怎么看从小到大?
如果字符串当中存在多个字符,第一次进行比较是,会按照第一个在Unicode编码表中出现的位置,进判定
Iterator接口的子接口----ListIterator:
两者之间的关系
从定义可知,他们是继承关系,也就是说Iterator是父接口,-ListIterator是子接口
public interface ListIterator<E> extends Iterator<E>
ListIterator和Iterator的区别
相同点:
功能相似,都可以对集合进行遍历
可以产生一个迭代器对象
不同点:
使用范围不同
Iterator可以应用于更多的集合,Set、List和这些集合的子类型。
而ListIterator只能用于List及其子类型。
遍历顺序不同
Iterator只能顺序向后遍历; ListIterator还可以逆序向前遍历
Iterator可以在遍历的过程中remove();ListIterator可以在遍历的过程中remove()、add()、set()
ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
集合操作类---Collections:
常用方法:
说明: 对于某些方法,里面的参数类型,只能是List集合,体现出了集合工具类的局限性。
例如: 排序----只针对List集合有效,其他集合无效
二分搜索法----只针对List集合有效,其他集合无效,此方法的前提,必须要保证List集合是自然顺序(从小到大)进行存储数据。
查询元素,如果存在则返回元素在集合当中的索引值
int index=Collections.binarySearch(list, 11);
排序的方法---局限性只能是List集合
Collections.sort(list);
复制集合的方法:
注意点:
* 1.List集合对象,默认的初始容量是10
* 2.目标列表(list)的长度至少必须等于源列表
* 3.目标集合必须要有元素,而且元素的个数不能少于源集合(list4)
实际操作就是吧list4中的元素复制到了list中,如果list4中有三个元素,list中有9个元素,那么list4中的三个元素在list中下标为0,1,2这三个位置上,原位置数据没了,等于覆盖了。
Collections.copy(list, list4);
求最大值和最小值
int max=Collections.max(list);
int min=Collections.min(list);
集合元素输出时进行反转
Collections.reverse(list);
线程安全化 ---- ArrayList类,特点: 重效率轻安全
List<Integer> list3=Collections.synchronizedList(list);
填充的方法(该方法会把list集合中的元素全部替换成520,慎用)
Collections.fill(list, 520);
外部比较器:
(Bean1是我创建的一个类,hp是类中的属性)
直接调用sort会出现编译错误,因为Bean1有各种属性
到底按照哪种属性进行比较,Collections也不知道,不确定,所以没法排
所以,即使使用的是List集合,也不太确定到底是按照什么顺序和属性进行排序的
此时,需要指定一个外部比较器,来确定排序规则。
Comparator<Bean1> h = new Comparator<Bean1>(){
@Override
public int compare(Bean1 h1, Bean1 h2) {
//按照hp进行排序
if(h1.hp>=h2.hp)
return 1; //正数表示h1比h2要大
else
return -1;
}
};
写完排序规则后,再次调用排序方法,这时候则就会开始从大到小排序了
Collections.sort(list,h);(该list是要排序的集合,h是外部比较器,也就是上边的那个)
来源:CSDN
作者:暖心尔之默意
链接:https://blog.csdn.net/m15231417197/article/details/103770065