为了在程序中保存数目不确定的对象,Java提供了一系列特殊的类,这些类可以储存任意类型的对象,并且长度可变,这些类统称为集合。集合类都位于Java。util包中,使用时必须导包。
集合按照其储存结构可以分为两大类,既单列集合Collection,和双列集合Map,两种集合的特点如下:
.)Collection:单列集合类的根接口,用于储存一系列符合某种规则的元素,他有两个重要的两个子接口,分别时List和Set。其中LIst的特点是元素有序,可重复。Set的特点是元素无序且不可重复。List接口的实现类有ArrayList和LinkedList。Set接口的实现类有:HashSet和TreeList。
.)Map:双列集合类的根接口,用于储存具有键(Key),值(Value)映射关系的元素,每个元素都包含了一对键值,其中键值不可重复且每个键最多只能映射到一个值,在使用Map集合时可以通过指定的键(Key找到对应的值(Value)。例如,通过一个学生的学号就能找到对应的学生。Map接口的实现类有HashMap和TreeMap。
集合时对象的容器,定义了对多个对象操作的常用方法,可实现数组的功能。
和数组的区别:
(1)数组的长度时固定的,集合的长度时不固定的。
(2)数组可以储存基本类型和引用类型,集合只能存储引用类型。
| 方法名 | 作用 |
|---|---|
| boolean add(Object 0) | 向集合中添加一个对象 |
| boolean addAll(Collection c) | 将一个集合中的所有对象添加的此集合中 |
| void clear() | 清空此集合中的所有对象 |
| boolean contains(Object 0) | 判断该集合中是否包含某个元素 |
| boolean equals(Object o) | 比较此集合与指定对象是否相等 |
| boolean isEmpty() | 判断此集合是否为空 |
| boolean remove(Object o) | 删除该集合中的指定对象 |
| int size() | 获取该集合中元素的个数 |
| Object[] toArray() | 将此集合转换为数组 |
package TestCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args){
//创建接口
Collection collection = new ArrayList();
//1.1添加元素
collection.add("香蕉");
collection.add("苹果");
collection.add("哈密瓜");
//1.2打印元素个数size()
System.out.println("元素个数"+collection.size());
System.out.println(collection);
//2.删除元素
collection.remove("香蕉");
collection.clear();//清空所有元素
System.out.println("删除之后元素个数"+collection.size());
//创建接口
Collection collection1 = new ArrayList();
//添加元素
collection1.add("香蕉");
collection1.add("苹果");
collection1.add("哈密瓜");
//3.遍历元素(重点)
//3.1使用增强for循环,由于集合中没有下标普通for循环无法获取元素
System.out.println("--------3.1使用增强for循环--------");
for (Object object: collection1) {
System.out.println(object);
}
//3.2使用迭代器:iterator():迭代器专门用来遍历集合
System.out.println("--------3.2使用迭代器:iterator():迭代器专门用来遍历集合--------");
//将集合使用iterator()方法交给迭代器迭代
Iterator it = collection1.iterator();
while(it.hasNext()){
String ob = (String) it.next();
System.out.println(ob);
it.remove();
}
System.out.println("元素个数"+collection1.size());
System.out.println("-----------------");
//4.判断
//contains():判断该集合中是否有某个元素
System.out.println(collection1.contains("西瓜"));
//isEmpty():判断该集合是否为空
System.out.println(collection1.isEmpty());
}
}
运行结果:
在程序开发中,经常需要遍历集合中的所有元素,针对这种需求,Java专门提供了一个接口Iterator。Iterator接口也是集合的一员,但它与Collection,Map接口不同。Collection接口与Map接口主要用于储存元素,而Iterator主要用于迭代访问(及遍历)Collection中的元素,因此Iterator对象也称为迭代器。
工作原理:
Iterator迭代器对象在遍历数组时,内部采用指针的方式来跟踪集合中的元素;如图:
在调用Iterator的next()方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next()方法后,迭代器的索引会向后移动一位指向第一个元素并将第一个元素返回,当再次调用next()方法时迭代器的索引会指向第二个元素并将元素返回,以此类推,直到hasNext()方法返回false,表示到达了集合尾部。
List子接口特点:有序的,有下标,元素可以重复,存入顺序和取出顺序一致。
继承了Collection的全部方法,还增加了自己特有的方法
| 方法名 | 作用 |
|---|---|
| void add(int index,Object o) | 在index位置插入对象o |
| boolean addAll(int index,Collection c | 将一个集合中的元素添加到此集合中的index位置 |
| Object get(int index) | 返回集合中指定位置的元素 |
| List subLIst(int fromIndex,int toIndex) | 返回fromIndex到toIndex直接的集合元素(含头不含尾) |
package TestCollection.TestList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
//List接口的使用
public class Demo01 {
public static void main(String[] args){
//创建集合对象
List list = new ArrayList();
//1.添加元素
System.out.println("-------1.添加元素------");
list.add("华为");
list.add("小米");
list.add("苹果");
list.add(1,"荣耀");//在下标1位置添加
System.out.println("元素的个数"+list.size());
System.out.println(list.toString());
//2.删除
System.out.println("-------2.删除------");
//list.remove("苹果");
list.remove(3);//使用下标来删除元素
System.out.println("删除之后元素的个数"+list.size());
System.out.println(list.toString());
//3.遍历(重点)
System.out.println("-------3.遍历------");
//3.1由于List有下标可以使用for循环
System.out.println("-------3.1使用for循环------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));//get()返回集合中指定位置的元素
}
//3.2使用增强for
System.out.println("-------3.2使用增强for------");
for (Object o:list) {
System.out.println(o);
}
//3.3使用迭代器
System.out.println("-------3.3使用迭代器------");
Iterator in =list.iterator();
while(in.hasNext()){
System.out.println(in.next());
}
//3.4使用列表迭代器List接口新加的迭代器
System.out.println("-------3.4使用列表迭代器顺向------");
ListIterator it =list.listIterator();
while(it.hasNext()){
System.out.println(it.nextIndex()+":" +it.next());
}
System.out.println("-------3.4使用列表迭代器逆向------");
//由于上面顺向遍历这时指针已经指在了最后一个之间调用逆向的方法就可以
while(it.hasPrevious()){
System.out.println(it.nextIndex()+":" +it.previous());
}
//4.判断
System.out.println("-------4.判断------");
System.out.println(list.contains("华为"));
System.out.println(list.isEmpty());
//5.获取
System.out.println("-------5.获取------");
System.out.println(list.indexOf("华为"));//获取元素的位置
System.out.println(list.remove(0));//获取某位置的元素
}
}
运行结果:
代码练习:
package TestCollection.TestList;
import java.util.ArrayList;
import java.util.List;
public class Demo02 {
public static void main(String[]args){
//创建集合
List it = new ArrayList();
//1.添加数字类数据(自动装箱)
System.out.println("------1.添加数字类数据------");
it.add(10);
it.add(20);
it.add(30);
it.add(40);
it.add(50);
System.out.println("元素个数"+it.size());
System.out.println(it.toString());
//2.删除
System.out.println("------2.删除------");
//it.remove(0);//通过下标删除
//it.remove((Object) 10);//强制转换
//it.remove(new Integer(10) );//强制转换通过基本类型包装类
System.out.println("删除之后元素个数"+it.size());
System.out.println(it.toString());
//3.补充subList():返回子集合xx-xx
System.out.println("------3.补充subList():返回子集合xx-xx------");
System.out.println(it.subList(2,4));//含头不含尾
}
}
运行结果:
ArrayList是List接口的实现类,它是程序中常见的一种集合,,在ArrayLIst中封装了一个长度可变的数组对象,当存入的元素超过数组长度时,ArrayLIst会在内存中分配一个更大的数组来储存这些元素,因此可以将ArrayList看作一个长度可变的数组。
ArrayList的大部分方法都是从都是从父类Collection和List继承过来的,其中add()方法和get()方法分别实现存入和取出。
简述:
数组结构实现,查询快,增删慢。
JDK1.2版本,效率快,线程不安全。
ArrayList原代码分析:
默认容量:DEFAULT_CAPACITY = 10;注意:创建集合后没有在集合中放入元素那么集合的默认容量为0;添加任意一个元素容量为10
存放元素的数组:Object[] elementDate
实际个数:int size
add()方法:添加元素:
在此之前用的比较多的是Vector:
数组结构实现,查询快,增删慢。
JDK1.0版本,运行效率慢,线程安全。
常用方法与其他的实现类基本一致。
ArrayList集合在查询元素时速度非常快,但是在增加或删除元素时效率就比较低,为了克服这种局限性,可以使用List接口的另一个实现类LinkedList。LinkedList集合内部维护了一个双向循环链表,链表的每一个元素都使用引用的方式来记住它前一个元素和后一个元素,从而可以将所有元素彼此链接起来,当插入一个新元素时,只需要需改这种元素之间的引用即可,删除一个节点也是如此。正因为有了这种储存结构,LinkedList集合在进行元素的增加和删除的效率上十分高,但是查询就慢了点。
简述:
链表结构,增删快,查询慢。
图解:
常用方法与父类的无异。
泛型是程序设计语言的一种特性。它允许程序员在使用强类型程序设计语言编写代码时定义一些可变部分,这些可变部分在运行前必须做出声明。在编程中用泛型来代替某个实现类型,而后通过实际调用时传入或推导的类型来对泛型进行替换以达到代码复用的目的。在使用泛型的过程中,操作的数据类型被指定为一个参数,这种参数类型在类,接口和方法中,分别称为泛型类,泛型接口,泛型方法。相对于传统上的形参,泛型可以使用参数具有更多类型上的变化,使代码更好的复用。
.)Java泛型是JDK1.5中引入的新特性。其本质是参数化类型,把类型作为参数传递。
.)常见的形式有泛型类,泛型接口,泛型方法。
语法:
好处:
1.提高代码复用性。
2.防止类型转换异常,提高代码的安全性。
package TestCollection.FanXing; public class Demo01{ //使用泛型T //1.创建变量 T t; //2.泛型作为方法的参数 public void show(T t){ System.out.println(t); } //泛型作为方法返回值 public T getT(){ return t; } }
泛型类的调用:
package TestCollection.FanXing;
public class TestDemo01 {
public static void main(String[]args){
//使用泛型类创建对象
//注意:1泛型只能使用引用类型。2.不同的泛型对象不能互相赋值
Demo01 d1 = new Demo01();
d1.t = "Hello";
d1.show("大家好!我是张三");
String str = d1.getT();
System.out.println(d1.t+"n");
Demo01 d2 = new Demo01();
d2.t = 100;
d2.show(200);
Integer in = d2.getT();
System.out.println(d2.t);
}
}
运行结果:
1.先创建接口:
package TestCollection.FanXing; public interface Demo02{ //静态常量 String name = "张三"; //泛型抽象方法 T sever(T t); }
2.实现接口:定义好实现类传入的类型
package TestCollection.FanXing; public class Demo02Imp implements Demo02{ @Override public String sever(String s) { System.out.println(s); return s; } }
测试代码:
//泛型接口实现类的测试
Demo02Imp imp = new Demo02Imp();
imp.sever("天王盖地虎,老王爱跳舞");
运行结果:
3.实现泛型接口2::实现泛型接口但是不让实现类确定传入的类型,可以将实现类也定成泛型类,实现类的就是接口。
代码实现:
package TestCollection.FanXing; public class Demo02Imp2implements Demo02 { @Override public T sever(T t) { System.out.println(t); return t; } }
测试代码:
//泛型接口泛型实现类测试
Demo02Imp2 imp2 = new Demo02Imp2();
imp2.sever(1000);
运行结果:
泛型类可以定义在泛型类中也可以定义在普通类中,泛型方法与所在的类是不是泛型类关系不大。
代码实现:
package TestCollection.FanXing;
public class Demo03 {
//泛型方法
//泛型方法2:返回值可以可以设置为泛型但是就要将泛型的值返回(return)出来
public T show(T t){
System.out.println("泛型方法"+t);
return t;
}
}
测试代码:
//泛型方法测试
Demo03 demo03 = new Demo03();
demo03.show("zzz");
demo03.show(100);
demo03.show(1.1);
}
运行结果:
概念:
参数化类型,类型安全的集合,强制集合的元素类型必须一致。
特点:
编译时既可检查,而非运行时抛出异常。
访问时不必类型转换(拆箱)。
不同泛型之间引用不能相互赋值,泛型不存在多态。
注意:
泛型集合一旦定了存放的元素类型就只能放者一种类型,
用普通的集合可以放所有类型的元素但是输出的时候都是默认为Object类型的
当想要强制转换类型时集合一旦放如了两种类型就容易保存
package TestCollection.FanXing;
import TestCollection.Student;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo04JiHe {
public static void main(String[]args){
//String类型的集合
ArrayList al = new ArrayList();
al.add("eee");
al.add("bbb");
al.add("ccc");
for (String string:al) {
System.out.println(string);
}
//添加之前定义的Student类的对象
ArrayList al2 = new ArrayList();
Student s1 = new Student("张三",55);
Student s2 = new Student("李四",23);
Student s3 = new Student("王五",35);
al2.add(s1);
al2.add(s2);
al2.add(s3);
for (Student student:al2) {
System.out.println(student);
}
System.out.println();
Iterator iterator = al2.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
运行结果:
Set接口和List接口一样,统一继承自Collection接口,它与Collection接口的方法基本一致,并没有对Collection接口进行功能扩展,只比Collection接口更严格了,与List接口不同的是,Set接口中元素无序,并且会以某种规则保证存入的元素不出现重复。
Set接口主要有两个实现类,分别是HashSet和TreeSet。其中HashSet是根据对象的散列值(哈希数值)来确定元素在集合中储存的位置,具有良好的存取和查找性能。TreeSet则以二叉树的方式来存储元素,它可以实现对集合中元素继续排列。
简述:
特点:无序,无下标,元素不重复。
Set实现类特点:
HashSet(重点):
.)基于HashCode实现元素不重复。
.)当存入的元素哈希码值相同时,会调用equal进行确认,如果为true,拒绝后者存入。
TreeSet:
基于排列顺序实现元素不重复。
实现了SortedSet接口,对集合元素进行自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则。
通过CompraeTo方法,判断元素是否重复
Set接口与父接口Collection无异:
package TestCollection.TestSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Demo01 {
public static void main(String[]args){
//创建集合
Set s1 = new HashSet<>();
//1.添加数据
s1.add("ppp");
s1.add("zzz");
s1.add("eee");
s1.add("kkk");
s1.add("ooo");
s1.add("ooo");//重复的并没有添加进去
System.out.println("元素个数"+s1.size());
System.out.println(s1.toString()+"n");
//2.删除元素
s1.remove("eee");//没有下标只能通过元素名删除元素
System.out.println("删除之后的元素个数:"+s1.size());
System.out.println(s1.toString()+"n");
//3.变量【重点】:没有有下标不能使用普通for循环
//3.1增强for
System.out.println("------增强for-------");
for (String str:s1) {
System.out.println(str);
}
System.out.println();
//3.2使用迭代器
System.out.println("------使用迭代器-------");
Iterator it = s1.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println();
//4.判断
System.out.println(s1.isEmpty());
System.out.println(s1.contains("kkk"));
}
}
运行结果:
HashSet集合常用方法与之前的方法无异
HashSet集合没有下标位置,元素不能重复是因为在存入集合时,集合会先调用hashCode()方法计算存储位置的哈希码值是否一致,不一致直接存入集合,一致的情况下再调用equals()方法比较对象内的值是否相等,不相等的存入集合,相等的判断为相同元素拒绝存入。
如图:
存储进入集合的元素不会按照存入顺序排列,会按照元素的大小(比如字母的大小,数字的大小)这样的规则进行排列。
代码演示:
package TestCollection.TestTreeSet;
import java.util.Iterator;
import java.util.TreeSet;
public class Demo01 {
public static void main(String[] args){
//创建集合
TreeSet ts = new TreeSet<>();
//1.添加元素
ts.add("qqq");
ts.add("www");
ts.add("eee");
ts.add("rrr");
ts.add("ddd");
System.out.println("元素个数:"+ts.size());
System.out.println(ts.toString()+"n");
//2.删除元素
ts.remove("rrr");
System.out.println("删除之后元素个数:"+ts.size());
System.out.println(ts.toString()+"n");
//3.遍历
//3.1使用增强for
System.out.println("------使用增强for-----");
for (String str:ts) {
System.out.println(str);
}
System.out.println();
//3.2使用迭代器
System.out.println("------使用迭代器------");
Iterator it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println();
//4.判断
System.out.println(ts.contains("qqq"));
System.out.println(ts.isEmpty());
}
}
运行结果:
如图所示,进入集合后会进行自动排序,常用方法还是一样的。但是我们用之前自己写的类创建对象进行添加集合就会报错,因为我们自己写的类它有姓名有年龄我们人知道怎么排序但是程序不知道就会报错,这就需要我们实现Comparable接口,重新实现比较规则。
代码演示:
package TestCollection.TestTreeSet;
import TestCollection.TestHashSet.Person;
import java.util.TreeSet;
public class Demo02 {
public static void main(String[]args){
//创建对象
TreeSet tp = new TreeSet();
Person ps1 = new Person("二丫",18);
Person ps2 = new Person("张三",18);
Person ps3 = new Person("李四",18);
Person ps4 = new Person("狗蛋",18);
Person ps5 = new Person("王婆",18);
Person ps6 = new Person("张麻子",17);
tp.add(ps1);
tp.add(ps2);
tp.add(ps3);
tp.add(ps4);
tp.add(ps5);
tp.add(ps6);
System.out.println("元素个数:"+tp.size());
System.out.println(tp.toString()+"n");
}
}
运行结果:
报错了。用自己写的类继承实现Comparable接口的比较方法。
先用自己写的类继承Comparable接口泛型写入继承的类就ok了然后重写对比方法:
//先按姓名比再按年龄比
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
然后我们再运行之前的集合看看效果:可以正常存入比较了
拓展:
除了让我们自己写的类继承Comparable接口重写比较方法,我们还可以在创建集合的时候调用Comparator接口(比较器),用匿名类实现比较方法这样我们自己写的类就不用去实现Comparable接口的比较类了。
代码演示:
package TestCollection.TestTreeSet;
import TestCollection.TestHashSet.Person;
import java.util.Comparator;
import java.util.TreeSet;
public class Demo03 {
public static void main(String[]args){
//创建集合,并指定比较规则
TreeSet tp = new TreeSet<>(new Comparator() {
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person ps1 = new Person("二丫",18);
Person ps2 = new Person("张三",18);
Person ps3 = new Person("李四",18);
tp.add(ps1);
tp.add(ps2);
tp.add(ps3);
System.out.println("元素个数:"+tp.size());
System.out.println(tp.toString()+"n");
}
}
运行结果:
**小案例:**要求:使用 TreeSet集合随机性字符串按长度从小到大排列
使用Comparator接口实现定制比较规则
package TestCollection.TestTreeSet;
import java.util.Comparator;
import java.util.TreeSet;
public class Demo04 {
public static void main(String[]args){
//创建集合,并指定比较规则
TreeSet ts = new TreeSet<>(new Comparator() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
//添加数据
ts.add("chongqing");
ts.add("beijing");
ts.add("shanghai");
ts.add("HelloWord");
ts.add("zhangmazi");
ts.add("shenzhen");
ts.add("tianjin");
System.out.println("元素个数:"+ts.size());
System.out.println(ts.toString());
}
}
运行结果:
Map接口是一种双列集合,他的每个元素都包含一个键对象Key和值对象Value,键和值对象之间存在一种对应关系,称为映射,从Map集合中访问元素时,只要指定了Key,就能找到对应的Value。下属的两个重要子类:
Map接口的特点:
用于存储任意键值对(Key—Value)。
键:无序,无下标,不允许重复(唯一)。
值:无序,无下标,允许重复。
| 方法名 | 作用 |
|---|---|
| void put(Object key,Object value) | 将对象存入集合中,关联键值,key重复则覆盖原值 |
| Object get(Object key) | 根据键获取对应的值 |
| Set keySet() | 返回所有的key |
| Collection | 返回包含所有值的Collection集合 |
| Set | 键值匹配的set集合 |
package TestMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo01 {
public static void main(String[]args){
//创建集合
Map m = new HashMap<>();
//1.添加元素
m.put("cn","中国");
m.put("uk","英国");
m.put("usa","霉国");
System.out.println("元素个数:"+m.size());
System.out.println(m.toString()+"n");
//2.删除
m.remove("usa");
System.out.println("删除之后元素个数:"+m.size());
System.out.println(m.toString()+"n");
//3.遍历
//3.1使用keySet()方法,返回的时Set集合
System.out.println("-------使用keySet()方法-----");
//Set kt = m.keySet();
for (String str:m.keySet()) {//简便写法
//get()方法,通过key(键)获取value(值)
System.out.println(str+"------->"+m.get(str));
}
System.out.println();
//3.2使用entrySet()方法,返回的之间就时键值对
System.out.println("------使用entrySet()方法------");
//返回的也是Set接口,泛型选择Map接口的Entry泛型类,Entry泛型选择元素的类型即可
//Set> set = m.entrySet();
for (Map.Entry me:m.entrySet()) {//简便写法
System.out.println(me.getKey()+"----->"+me.getValue());
}
System.out.println();
//判断
System.out.println(m.containsKey("cn"));
System.out.println(m.containsValue("英国"));
}
}
运行结果:
KDK1.2版本,线程不安全,运行效率快,允许使用null作为key或value。
**常用的方法:**还是和之前的一样,只有遍历的时候有的不一样不信你看:
package TestMap.TeatHashMap;
import java.util.HashMap;
import java.util.Map;
public class Demo01 {
public static void main(String[]args){
//创建集合,
HashMap hm = new HashMap();
//添加元素
Student s1 = new Student("法外狂徒张三",9527);
Student s2 = new Student("菊中君:王大瓜",9867);
Student s3 = new Student("财富移客:黄毛",3387);
Student s4 = new Student("门窗克星:时六",9257);
Student s5 = new Student("金三角求生大师:峰哥",3657);
hm.put(s1,"全美第三人民精神病院下属监狱");
hm.put(s2,"全美第三人民精神病院下属监狱");
hm.put(s3,"全美第三人民精神病院下属监狱");
hm.put(s4,"全美第三人民精神病院下属监狱");
hm.put(s5,"全美第三人民精神病院下属监狱");
System.out.println("元素个数:"+hm.size());
System.out.println(hm.toString()+"n");
//删除
hm.remove(s4);
System.out.println("删除之后元素个数:"+hm.size());
System.out.println(hm.toString()+"n");;
//3.遍历
//3.1使用keySet()方法遍历
System.out.println("-----使用keySet()方法遍历------");
for (Student student:hm.keySet()) {
System.out.println(student.toString()+"----->"+hm.get(student));
}
System.out.println();
//3.2使用entrySet()方法遍历
System.out.println("------使用entrySet方法遍历()------");
for (Map.Entry me:hm.entrySet()) {
System.out.println(me.getKey()+"------>"+me.getValue());
}
System.out.println();
//4.判断
System.out.println(hm.isEmpty());
System.out.println(hm.get(s1));
System.out.println(hm.containsKey(s2));
}
}
运行结果:
总结:
1.HashMap集合刚创建时,内存空间时null,为了节省空间。当添加第一个元素时,容量调整为16。
2.当元素个数大于阈值时(16*0.75=12),会进行扩容,扩容之后的大小是之前的2倍,目的是减少调整元素个数。
3.JDK1.8当每个链表长度大于8时,并且数组元素大于等于64时,会调整为红黑树,目的为了提高执行效率。
4.JDK1.8当红黑数小于6时,会调整为链表
5.JDK1.8以前链表时从头插入,JDK1.8之后链表时从尾插入。
实现了SortedMap接口(是Map的子接口),可以对Key进行自动排序。
常用方法:
TreeMap集合常用方法与TreeSet集合常用方法是一致的。这里就不再导入代码了。
集合工具类,定义了除存取以外的集合常用方法。
| 方法名 | 作用 |
|---|---|
| public static void reverse(List> list) | 反转集合中元素的顺序 |
| public static void shuffle(List> list) | 随机重置集合元素的顺序 |
| public static void sort(List | 升序排序(元素类型必须实现Comparable接口) |
| 代码演示: |
package TestCollection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class TestCollections {
public static void main(String[]args){
List is = new ArrayList<>();
is.add(10);
is.add(2);
is.add(0);
is.add(4);
is.add(59);
//sort排序
System.out.println("排序之前"+is.toString());
Collections.sort(is);
System.out.println("排序之后"+is.toString()+"n");
//binarySearch二分查找
int i =Collections.binarySearch(is,10);
System.out.println(i+"n");
//copy复制
List is2 = new ArrayList<>();
for (int j = 0; j < is.size(); j++) {
is2.add(0);
}
Collections.copy(is2,is);
System.out.println(is2.toString()+"n");
//reverse反转
Collections.reverse(is);
System.out.println("反转之后"+is.toString()+"n");
//shuffle 打乱
Collections.shuffle(is);
System.out.println("打乱之后"+is.toString()+"n");
//补充知识点
//1.List转成数组
System.out.println("-----List转成集合-----");
Integer[] arr = is.toArray(new Integer[0]);
System.out.println(arr.length);
System.out.println(Arrays.toString(arr)+"n");
//2.数组转成集合
System.out.println("---数组转成集合---");
String[] names = {"张三","李四","王五"};
//
List is3 = Arrays.asList(names);
System.out.println(is3);
//基本类型数组转为集合时,要使用包装类
Integer [] num = {100,200,300};
List li = Arrays.asList(num);
System.out.println(li+"n");
}
}
运行结果:



