Java集合框架
文章目录
目录
- 集合的概念
- Collection接口
- Collection父接口
- List接口
- List实现类在这里插入代码片
- 泛型和工具类
- Set接口和实现类
- Map接口与实现类
- Collections工具类
1、什么是集合
1.1集合的概念
对象的容器,定义了多个对象进行操作的常用方法;可实现数组的功能
1.2集合和数组的区别
- 1 数组的长度固定,集合长度不固定
- 2 数组可以存储基本类型和引用类型,集合只能存储引用类型
2、 Collection体系结构:
3、 Collection父接口
- 特点:代表一组应以类型的对象,无序、无下标、不能重复
- 方法
- boolean add (0bject obj) //添加一个对象。
- boolean addAl1 (Collection c) //将一个集合中的所有对象添加到此集合中。
- void clear() //清空此集合中的所有对象。
- boolean contains (Object o) //检查此集合中是否包含0对象
- boolean equals (object o) //比较此集合是否与指定对象相等。
- boolean isEmpty () //判断此集合是否为空
- boolean remove (0bject o) //在此集合中移除0对象
- int size() //返回此集合中的元素个数。
- Object[] toArray() //将此集合转换成数组。
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
//1 添加元素
collection.add("西瓜");
collection.add("苹果");
collection.add("梨子");
System.out.println(collection.size());//打印集合长度
System.out.println(collection);
//2 删除元素
// collection.remove("苹果");
//3 遍历元素
//3.1 增强for
for (Object o : collection) {
System.out.println(o);
}
System.out.println("---------------------");
//3.2 使用迭代器:专门用来遍历集合的方法(hasNext,next,remove)
/*
hasNext 有没有下一个元素
next 获取下一个元素
remove 删除当前元素
*/
Iterator it = collection.iterator();
while (it.hasNext()){
String s = (String) it.next();
System.out.println(s);
// collection.remove(s);
//.ConcurrentModificationException 并发修改异常,迭代器中不能用Collection修改
// it.remove();//可以使用迭代器的方法删除
}
//4 判断
System.out.println(collection.contains("西瓜"));//判断有没有元素西瓜
System.out.println(collection.isEmpty());//判断是否为空
}
4、List子接口
特点:有序、有下标、元素可以重复
- 有序集合(也称为序列 )。 该界面的用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
方法:
- void add (int index, Object o) //在index位置插入对象0。
- boolean addAll (int index, Collection c) //将一个集合中的元素添加到此集合中的index位置。
- Object get (int index) //返回集合中指定位置的元素。
- List sublList (int fromIndex, int toIndex) //返回fromlndex和toIndex之间的集合元素。
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList();
//1 添加元素
list.add("小米");
list.add(0,"华为");//在第0处添加
list.add("水果");
System.out.println(list.toString());//[华为, 小米, 水果]
//2 删除元素
list.remove(2);
System.out.println(list.toString());//[华为, 小米]
//3 遍历
//3.1 for
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));//华为小米
}
//3.2增强for
for (Object o : list) {
System.out.print(o);//华为小米
}
System.out.println("_______________");
//3.3迭代器
Iterator it = list.iterator();
while (it.hasNext()){
System.out.print(it.next());//华为小米
}
//3.4 listIterator列表迭代器,比Iterator强大,可以前后遍历,修改元素
ListIterator lt = list.listIterator();
while (lt.hasNext()){
System.out.println(lt.nextIndex()+":"+lt.next());//0:华为1:小米
}
//从后往前
while (lt.hasPrevious()){
System.out.println(lt.previousIndex()+":"+lt.previous());//1:小米0:华为
}
//4 判断
System.out.println(list.contains("华为"));//true
System.out.println(list.isEmpty());//true
//5 获取位置
System.out.println(list.indexOf("华为"));//0
}
4.1、数字及subLIst
public static void main(String[] args) {
List list = new ArrayList();
//1 添加数字(自动装箱)Integer包装类
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
System.out.println(list.toString());
//删除
// list.remove(0);
// list.remove((Object) 20);
// list.remove((Integer)20);
// list.remove(new Integer(20));//数字
System.out.println(list.toString());
//subList 含头不含尾
List sublist = list.subList(1,3);
System.out.println(sublist.toString());//[30, 40]
}
5、List实现类
- ArrayList(重点)
- 数组结构实现,查询快、增删慢
- jdk1.2版本,运行效率快、线程不安全
- Vector
- 数组结构实现,查询快、增删慢
- jdk1.0版本,运行慢,线程安全
- LinkedList(常用)
- 链表结构实现,增删快,查询慢
- 链表首先有个head元素,添加元素,第一个就指向第二个元素以此类推
5.1、ArrayList(重点)
- 数组结构实现,查询快、增删慢
- 没有向集合中添加元素时,容量为0
- //数组容量超过10以后再添加元素,就扩容到原来的1,5倍,
int newCapacity = oldCapacity + (oldCapacity >> 1);
例子
public static void main(String[] args) {
Student s1 = new Student("张三",22);
Student s2 = new Student("李四",22);
Student s3 = new Student("麻子",22);
//创建集合
ArrayList arr = new ArrayList<>();
//1 添加
arr.add(s1);
arr.add(s2);
arr.add(s3);
System.out.println(arr.toString());
System.out.println("_____________");
//2 删除
// arr.remove(s1);
System.out.println(arr.toString());
System.out.println("_____________");
//3 遍历
//迭代器
Iterator it = arr.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("_____________");
//列表迭代器
ListIterator lit = arr.listIterator();
while (lit.hasNext()){
System.out.println(lit.next());
}
System.out.println(lit.nextIndex());
System.out.println("_____________");
System.out.println(lit.previousIndex());
while (lit.hasPrevious()){
System.out.println(lit.previous());
}
}
ArrayList源码
/*
源码:
默认容量大小 DEFAULT_CAPACITY = 10
空数组 EMPTY_ELEMENTDATA = {}
空数组 DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
存放元素的数组 elementData
元素个数 size
*/
//构造方法
public ArrayList() {
//没有向集合中添加元素时,容量为0
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//空数组
}
//添加元素 add
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//add方法里的ensureCapacityInternal()
//transient Object[] elementData;
private void ensureCapacityInternal(int minCapacity) {
// 10
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//ensureCapacityInternal方法里的alculateCapacity
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//elementData
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//Math.max()取最大值,(a >= b) ? a : b
// 10 size+1 =1
return Math.max(DEFAULT_CAPACITY, minCapacity);//这里返回10
}
return minCapacity;
}
//ensureCapacityInternal方法里的ensureExplicitCapacity
private void ensureExplicitCapacity(int minCapacity) {
//默认为0
modCount++;//1
// overflow-conscious code
// 10 - 0
if (minCapacity - elementData.length > 0)
// 10
grow(minCapacity);
}
//ensureExplicitCapacity方法里的grow,,核心
// 10
private void grow(int minCapacity) {
// overflow-conscious code
// 0
int oldCapacity = elementData.length;
// 0 0 0
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 0 10
if (newCapacity - minCapacity < 0)
// 10
newCapacity = minCapacity;
// 10 ( Integer.MAX_VALUE - 8):很大
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//空 空 10
elementData = Arrays.copyOf(elementData, newCapacity);
//创建一个容量为10的数组
}
//最后 0 传进来的元素
elementData[size++] = e;
//添加元素到数组
//数组容量超过10以后再添加元素,就扩容到原来的1,5倍,
int newCapacity = oldCapacity + (oldCapacity >> 1);
5.2、Vector集合(不常用)
Vector
类实现了可扩展的对象数组。 像数组一样,它包含可以使用整数索引访问的组件。 但是,Vector
的大小可以根据需要增长或缩小,以适应在创建Vector
之后添加和删除项目。
public static void main(String[] args) {
//创建集合
Vector vt = new Vector<>();
//1 添加元素
vt.add("苹果");
vt.add("草莓");
vt.add("西瓜");
System.out.println(vt.size());//3
//2 删除,remove
//3 遍历
//for,增强for
//jdk1.2之前,使用枚举器
Enumeration en = vt.elements();
while (en.hasMoreElements()){
System.out.println(en.nextElement());
}
//4判断
System.out.println(vt.contains("西瓜"));
System.out.println(vt.isEmpty());
//5 其他方法
vt.firstElement();
vt.lastElement();
vt.elements();
}
5.3、LinkedList
LinkedList(常用)
- 链表结构实现,增删快,查询慢,双向链表
- 链表首先有个head元素,添加元素,第一个就指向第二个元素以此类推
常用方法
public static void main(String[] args) {
Student s1 = new Student("张三",22);
Student s2 = new Student("李四",22);
Student s3 = new Student("麻子",22);
//创建元素
LinkedList linkedList = new LinkedList<>();
//1 添加元素
linkedList.add(s1);
linkedList.add(s3);
linkedList.add(s2);
System.out.println(linkedList.toString());
//2 删除
// linkedList.remove(s1);
//3 遍历
//for
// for (int i = 0; i < linkedList.size(); i++) {
// System.out.println(linkedList.get(i));
// }
//增强for
// for (Object o : linkedList) {
// System.out.println(o);
// }
//迭代器
// Iterator it = linkedList.iterator();
// while (it.hasNext()){
// System.out.println(it.next());
// }
//列表迭代器
ListIterator lt = linkedList.listIterator();
while (lt.hasNext()){
System.out.println(lt.next().toString());
}
//4 判断
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
//5 获取
System.out.println(linkedList.indexOf(s1));//获取下标
}
LinkedList 源码
- size = 0
- first 头 last 尾
- 前一个指向后一个,后一个指向前一个
//构造方法空
public LinkedList() {
}
//add方法
public boolean add(E e) {
linkLast(e);
return true;
}
//linkLast(e);
void linkLast(E e) {
// null
final Node<E> l = last;
// null 元素
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
//Node<E>
private static class Node<E> {
//item当前元素
E item;
//下一个节点
Node<E> next;
//前一个节点
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
5.4 ArrayList和LinkedList的区别
- LinkedList
- 查询慢:需要从头或从尾一个个找
- 删除快:删除一个元素,只需要改变指向关系就可以了
5.5、小问题
列表迭代器ListIterator
- nextIndex()默认是0,previousIndex() : nextIndex()-1 = -1
- 直接逆遍历需要先把遍历一次,让nextIndex()到最后一位
/*
有三个学生,Student{name='张三', age=22}
Student{name='李四', age=22}
Student{name='麻子', age=22}
*/
ListIterator lit = arr.listIterator();
//正向遍历
while (lit.hasNext()){
System.out.println(lit.next());
}
System.out.println(lit.nextIndex());//3
System.out.println(lit.previousIndex());//2
while (lit.hasPrevious()){
System.out.println(lit.previous());
}
//注释掉正向遍历后
// while (lit.hasNext()){
// System.out.println(lit.next());
// }
System.out.println(lit.nextIndex());//0
System.out.println("_____________");
System.out.println(lit.previousIndex());//-1
while (lit.hasPrevious()){//就不能遍历了
System.out.println(lit.previous());
}
//可以在逆向遍历之前正向遍历一遍解决
6、泛型
- Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
- 常见形式有泛型类、泛型接口、泛型方法。
- 语法:
- .<T,…> T称为类型占位符,表示一种引用类型。
- 好处:
- (1)提高代码的重用性:比如传递时可以传递任意类型的参数
- (2)防止类型转换异常,提高代码的安全性
6.1、泛型类
- 语法,类名
- T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
- 泛型只能使用引用类型
- 不同泛型类型对象之间不能相互赋值
/**
* 泛型类
* 语法,类名<T>
* T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
*/
public class MyGeneric<T> {
//使用泛型T
//1 创建变量
T t;
//2 泛型作为方法的参数
public void show(T t){
System.out.println(t);
}
//3泛型的方法的返回值
public T getT() {
return t;
}
}
public static void main(String[] args) {
//使用泛型类创建变量
//注意,1 泛型只能使用引用类型,2 不同泛型类型对象之间不能相互赋值
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t = "hello";
myGeneric.show("大家好");//大家好
String str = myGeneric.getT();
System.out.println(str);//hello
MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
myGeneric1.t = 100;
myGeneric1.show(200);//200
Integer integer = myGeneric1.getT();
System.out.println(integer);//100
}
6.2、泛型接口
- 定义泛型接口,接口名
- 注意:不能用泛型创建常量
- 实现类
- 1:可以在实现类上泛型直接指定类型,方法使用对应类型
- 2:实现类泛型不指定类型,使用的时候再指定
例子:
/**
* 泛型接口
* 语法:接口名<T>
* 注意:不能用泛型创建常量
*/
public interface MyInterface<T> {
String name = "张三";
T server(T t);
}
//实现类1 指定类型<String>
public class MyInterfaceImpl implements MyInterface<String> {
@Override
public String server(String t) {
System.out.println(t);
return t;
}
}
//实现类2 不指定类型
public class MyInterfaceImpl2<T> implements MyInterface<T> {
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
//测试
public static void main(String[] args) {
MyInterfaceImpl impl1 = new MyInterfaceImpl();
impl1.server("ttttttttttttt");//tttttttttt
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
impl2.server(2020);//2020
}
6.3、泛型方法
- 语法,方法返回值类型前加:public void show(){}、
- 传递的类型是由传递的值决定
//泛型方法
public <T> T show(T t){
System.out.println("泛型方法"+t);
return t;
}
//调用
//泛型方法
MyGenericMethod mg = new MyGenericMethod();
//传递的类型是由传递的值决定
mg.show(222);
mg.show("行啊");
6.4、泛型集合
概念:
- 参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点:
- 编译时即可检查,而非运行时抛出异常
- 访问时,不需要类型转换(拆箱)
- 不同泛型之间引用不能相互赋值,泛型不存在多态
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList();
arrayList.add("aaa");
arrayList.add("bbb");
for (String s : arrayList) {
String ss = s;
System.out.println(ss);
}
Student s1 = new Student("aaa",11);
Student s2 = new Student("bbb",22);
ArrayList<Student> arrayList1 = new ArrayList<>();
arrayList1.add(s1);
arrayList1.add(s2);
Iterator<Student> it = arrayList1.iterator();
while (it.hasNext()){
//添加泛型指定Student类型后,获取的也是Student类型
Student st = it.next();
System.out.println(st);
}
}
7、Set子接口
特点:
- 无序、无下标、元素不可以重复
方法:
- 全部继承Collection的方法
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<>();
//1 添加数据
set.add("苹果");
set.add("西瓜");
set.add("香蕉");
System.out.println(set.toString());//[苹果, 香蕉, 西瓜]
//2 删除
// set.remove("香蕉");
//3 遍历
//增强for
for (String s : set) {
System.out.println(s);
}
//迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
7.1、Set实现类(HashSet)
-
基于HashCode计算元素存放位置
-
当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,,则拒绝后者存入
-
存储过程
- 根据hashcode计算保存位置,如果位置为空,直接保存,如果不为空执行第二步
- 执行equals,如果equals为true,认为是重复,否则形成链表
public static void main(String[] args) {
//创建集合
HashSet<Person> hashSet = new HashSet<>();
//添加数据
Person s1 = new Person("张三",11);
Person s2 = new Person("麻子",22);
Person s3 = new Person("蓝色",33);
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(new Person("张三",11));//是不同对象可以添加
//重写hashcode,和equals后相同元素就不能添加了
System.out.println(hashSet);
//删除
// hashSet.remove(s1);
//重写hashcode,和equals后相同元素就不能删除了
hashSet.remove(new Person("张三",11));
}
7.2、TreeSet
特点:
- 基于排序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
@Override
//Person类:实现Comparable接口,重新compareTo()方法
//先比姓名再比年龄
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
/**
* TreeSet
* 存储结构:红黑树
*
*/
public class Demo2 {
public static void main(String[] args) {
TreeSet<Person> person = new TreeSet<>();
//1 添加元素
Person p1 = new Person("xyz",18);
Person p2 = new Person("aaa",33);
Person p3 = new Person("ddd",22);
Person p4 = new Person("ddd",20);
person.add(p1);
person.add(p2);
person.add(p3);
person.add(p4);
System.out.println(person);
//2 删除元素
person.remove(new Person("ddd",20));
//3 遍历
//增强for
//迭代器
}
自定义比较规则
- 先比年龄,再比姓名
public static void main(String[] args) {
//内部类
TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
@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 p1 = new Person("xyz",18);
Person p2 = new Person("aaa",33);
Person p3 = new Person("ddd",22);
Person p4 = new Person("ddd",20);
ts.add(p1);
ts.add(p2);
ts.add(p3);
ts.add(p4);
System.out.println(ts);
}
- 字符串按长度进行排序
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
//长度从长往短排
public int compare(String o1, String o2) {
int n1 = o2.length()-o1.length();
int n2 = o1.compareTo(o2);
return n1==0 ? n2:n1;
}
});
ts.add("sidfhkajlsdhfj");
ts.add("aaas");
ts.add("bbb");
ts.add("cccds");
ts.add("caaas");
System.out.println(ts);
//[sidfhkajlsdhfj, caaas, cccds, aaas, bbb]
}
8、Map集合
8.1、Map父接口
特点:
- 存储一对数据(Key-Value),无序、无下标,键不可重复,值可以重复
方法:
- V put (K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
- Object get (object key) //根据键获取对应的值。
- KeySet //返回所有key。
- Collection values () //返回包含所有值的Collection集合。
- Set<Map. Entry<K, V>> //键值匹配的Set集合。
- entrySet() 返回此映射中包含的映射关系的Set视图。
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
//1 添加
map.put("pg","苹果");
map.put("xg","西瓜");
map.put("xj","香蕉");
System.out.println(map.size()+":"+map);
//2 删除
// map.remove("xg");
// System.out.println(map.size()+":"+map);
//3 遍历
// 1 keySet
// Set<String> s = map.keySet();
for (String s1 : map.keySet()) {
System.out.println(s1+":"+map.get(s1));
}
// 2 使用entrySet()遍历
// Set<Map.Entry<String, String>> entries = map.entrySet();
// for (Map.Entry<String, String> entry : entries) {
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
//4 判断
System.out.println(map.containsValue("西瓜"));
System.out.println(map.isEmpty());
}
8.1、HashMap*
-
JDK1.2支持,线程不安全,运行效率快;允许使用null作为key或Value
-
构造方法
-
HashMap()
构造一个空的HashMap
,默认初始容量(16)和默认负载系数(0.75)。 -
HashMap(int initialCapacity)
构造一个空的HashMap
具有指定的初始容量和默认负载因子(0.75)。 -
HashMap(int initialCapacity, float loadFactor)
构造一个空的HashMap
具有指定的初始容量和负载因子。 -
HashMap(Map<? extends K,? extends V> m)
构造一个新的HashMap
与指定的相同的映射Map
-
基于哈希表的实现的
Map
接口。 此实现提供了所有可选的地图操作,并允许null的
值和null
键。 (HashMap
类大致相当于Hashtable
,除了它是不同步的,并允许null)。这个类不能保证地图的顺序; 特别是,它不能保证订单在一段时间内保持不变。
public static void main(String[] args) {
HashMap<Student,String> hm = new HashMap<>();
//添加元素
Student s1 = new Student("孙悟空",100);
Student s2 = new Student("猪八盖",101);
Student s3 = new Student("沙僧",102);
hm.put(s1,"贵阳");
hm.put(s2,"金阳");
hm.put(s3,"火车站");
hm.put(new Student("沙僧",102),"北站");//hashcode不同可以添加,可以通过重新hashcode和equals
System.out.println(hm.size()+":"+hm);
//2 删除 remove
//3 遍历
// KeySet
for (Student student : hm.keySet()) {
System.out.println(student+":"+hm.get(student));
}
//entrySet
for (Map.Entry<Student, String> studentStringEntry : hm.entrySet()) {
System.out.println(studentStringEntry.getKey()+":"+studentStringEntry.getValue());
}
}
HashMap小结:
- 刚创建集合时集合的长度为0,(节省空间)
- (put)添加数据时集合长度调整为16(0-15)
- 当数据个数达到阈值(16*0.75)12时,扩容为原来的两倍,32(16的二倍)
- jdk1.8当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,日的提高执行效率
- jdk1.8当链表长度小于6时,调整成链表
- jdk 1.8以前,链表时头插入, jdk1.8以后时是尾插入
HashMap和HashSet
- HashSet实际上使用的是HashMap的Key
8.2、Hashtable和Properties
- JDK1.0版本,线程安全,运行效率慢,键值不允许为null
- 子类:Properties
- 要求键值都是String,通常用于配置文件的读取
8.3、TreeMap
- 实现了sort
- 结构:红黑树
public static void main(String[] args) {
TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1 = o1.getStuNo()-o2.getStuNo();
return n1;
}
});
//1.添加对象
Student s1 = new Student("孙悟空",100);
Student s2 = new Student("猪八盖",101);
Student s3 = new Student("沙僧",102);
tm.put(s1,"北京");
tm.put(s2,"上海");
tm.put(s3,"深圳");
System.out.println(tm.size()+":"+tm);
tm.put(new Student("沙僧1",102),"南京");//替换了value
System.out.println(tm.size()+":"+tm);
//2 删除,remove
//3 遍历
//keySet
for (Student student : tm.keySet()) {
System.out.println(student+":"+tm.get(student));
}
//entrySet
for (Map.Entry<Student, String> entry : tm.entrySet()) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
//4 判断,containsKey,IsEntry
}
TreeSet 和TreeMap
- TreeSet使用的TreeMap的key
9、Collections工具类
概念:
- 集合工具类,定义了除了存取以外的集合常用方法。
- 方法:
- public static void reverse(List<?> list) //反转集合中元素的顺序
- public static void shuffle(List<?> list) //随机重置集合元素的顺序
- public static void sort (List list) //升序排序(元素类型必须实现Comparable接口)
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(22);
list.add(5);
list.add(2);
list.add(44);
list.add(11);
//sort 排序 默认升序
Collections.sort(list);
System.out.println(list);//[2, 5, 11, 22, 44]
//binarySearch 二分查找(先排序) ,有就返回下标,没有返回负数
int i = Collections.binarySearch(list,444);//-6
System.out.println(i);
//copy复制
List<Integer> list1 = new ArrayList<>();
//copy方法复制的对象没有长度会报异常IndexOutOfBoundsException
for (int j = 0; j < list.size(); j++) {
//先赋值0
list1.add(0);
}
Collections.copy(list1,list);
System.out.println(list1);//[2, 5, 11, 22, 44]
//reverse反转
Collections.reverse(list);
System.out.println(list);//[44, 22, 11, 5, 2]
//shuffle 打乱,每次都不一样
Collections.shuffle(list);
System.out.println(list);//[22, 2, 5, 11, 44]
}
数组集合转换
//list转成数组,长度和list长度一样
Integer[] it = list.toArray(new Integer[0]);
System.out.println(it.length+":"+ Arrays.toString(it));//5:[11, 44, 5, 2, 22]
//把数组转成集合 ,创建的时候固定了长度,不能添加或删除,可以修改
String[] names = {"aaa","bbb","ddd","FFF"};
List<String> list2 = Arrays.asList(names);
//出现异常UnsupportedOperationException
// list2.add("sss");
System.out.println(list2);//[aaa, bbb, ddd, FFF]
//基本类型数组转集合时需要写包装类型
Integer[] nums = {111,222,33,44,55};
List<Integer> integers = Arrays.asList(nums);
System.out.println(integers);//[111, 222, 33, 44, 55]
小问题