java-集合
集合
概念
集合:对象的容器,定义了多个对象进行操作的常用方法,可实现类似的数组的功能。
有Collection集合和Map集合
与数组区别
- 数组长度固定,集合不固定
- 数组可存基本类型和引用类型 ,集合只能存引用类型
Collection集合体系
Collection为集合的根接口
List接口特点:有序,有下标,元素重复
Set接口特点:无序,没下标,元素不可以重复
Collection父接口
API文档定义:Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
方法:(引用自java API 1.6)
- boolean add(E e)
确保此 collection 包含指定的元素(可选操作)- boolean addAll(Collection<? extends E> c)
将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。- void clear()
移除此 collection 中的所有元素(可选操作)。- boolean contains(Object o)
如果此 collection 包含指定的元素,则返回 true。- boolean containsAll(Collection<?> c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。- boolean equals(Object o)
比较此 collection 与指定对象是否相等。- Iterator iterator()
返回在此 collection 的元素上进行迭代的迭代器。- boolean remove(Object o)
从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。- boolean removeAll(Collection<?> c)
移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。- boolean retainAll(Collection<?> c)
仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。- int size()
返回此 collection 中的元素数。- Object[] toArray()
返回包含此 collection 中所有元素的数组。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionTest {
public static void main(String[] args) {
//1.创建集合
Collection collection = new ArrayList();
//2.添加元素
collection.add("儿");
collection.add("童");
collection.add("节");
collection.add("快");
collection.add("乐");
collection.add("!");
System.out.println("元素个数"+collection.size());
System.out.println(collection);
//3.删除元素
collection.remove("!");
System.out.println("删除后元素个数"+collection.size());
System.out.println(collection);
collection.clear();// 删除全部
System.out.println("clear元素个数"+collection.size());
System.out.println(collection);
//重新赋值
collection.add("儿");
collection.add("童");
collection.add("节");
collection.add("快");
collection.add("乐");
collection.add("!");
//4.遍历元素
//4.1增强for循环
System.out.println("==========增强for循环 ===========");
for(Object o:collection){
System.out.println(o);
}
//4.2迭代器iterator
System.out.println("==========迭代器===========");
Iterator iterator=collection.iterator();
//迭代器iterator返回对象为Iterator<>
//有三个方法
/*
hasNext() 判读有没有下个元素
next()读取下个元素
remove()删除当前元素(选用)
*/
while (iterator.hasNext()){
//Object o = iterator.next(); 知道是字符串类型可以强制转换
String object = (String)iterator.next();
System.out.println(object);
iterator.remove();
}
System.out.println("元素个数:"+collection.size());
//判断
collection.add("儿童");
System.out.println(collection.contains("儿童"));//判断包含
System.out.println(collection.contains("少年少女"));
System.out.println(collection.isEmpty());//判断是否为空
collection.clear();
System.out.println(collection.isEmpty());
}
}
结果:
注意:用clear方法清除,只是清除了Collection里的对象地址,对象仍存在。
public class Collectiondemo
{
public static void main(String[] args) {
Collection collection = new ArrayList();
Student s1 = new Student(1, "11");
Student s2= new Student(2, "22");
Student s3 = new Student(3, "33");
collection.add(s1);
collection.add(s2);
collection.add(s3);
System.out.println("collection:"+collection);
collection.clear();
System.out.println("clear后collection:"+collection);
System.out.println(s1.toString());
System.out.println(s2.toString());
System.out.println(s3.toString());
}
static class Student{
private String name;
private Integer id;
public Student( Integer id,String name) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
}
结果:
List接口
List接口特点:有序,有下标,元素可以重复
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
boolean add(E e)
向列表的尾部添加指定的元素(可选操作)。
void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(Collection<? extends E> c)
添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。
boolean addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
E get(int index)
返回列表中指定位置的元素。
List subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListDemo {
public static void main(String[] args) {
//创建List集合
List list = new ArrayList();
list.add(11);
list.add("阿巴阿巴");
list.add(22);
System.out.println("元素个数"+list.size());
System.out.println(list);
//继承Collection接口,可使用Collection方法
//迭代器(可使用列表迭代器ListIterator) 与Iterator区别:可以向后遍历,也可对元素进行添加,删除,修改
ListIterator listIterator = list.listIterator();
System.out.println("向后遍历");
while (listIterator.hasNext()){
System.out.println(listIterator.nextIndex() + ":"+listIterator.next());//打印角标和内容
if(listIterator.nextIndex()==0){
listIterator.set("yiya");//set方法对元素 next()进行修改
}
}
System.out.println("向前遍历");
while (listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex() + ":"+listIterator.previous());//打印角标和内容
}
//获取元素位置
System.out.println("获取阿巴阿巴位置"+list.indexOf("阿巴阿巴"));
//注意 删除操作
list.remove(1);//
System.out.println(list);
// list.remove(22); 会报错,删除下表为22的元素,没有这个元素
list.remove(new Integer("22"));
System.out.println(list);
//sublist 返回子集合
List l1 = list.subList(0, 1);// 返回左闭右开list
System.out.println(l1);
}
}
结果:
List接口实现类
ArrayList
- 数组结构实现:查询快,增删慢;
- JDK1.2 运行效率快,但线程不安全
Vector
- 数组结构实现:查询快,增删慢;
- .JDK1.0 运行效率慢,但线程安全
Linklist
- 链表结构实现,查询慢,增删快
ArrayList
默认存储容量 10;
注意:如果未向集合中添加元素,容量为零 扩容时,每次扩容后的大小是以前的1.5倍
private static final int DEFAULT_CAPACITY = 10;
在源码中存放元素的数组 elementData
实际元素个数 size
import java.util.ArrayList;
import java.util.Objects;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
//ArrayList 是List的实现类,继承其方法
Teacher t1 = new Teacher("苍老师", 30);
Teacher t2 = new Teacher("三上老师", 30);
Teacher t3 = new Teacher("泷泽老师", 30);
//添加元素
arrayList.add(t1);
arrayList.add(t2);
arrayList.add(t3);
System.out.println("元素个数"+arrayList.size());
System.out.println(arrayList);
//删除元素
arrayList.remove(new Teacher("苍老师",30));
System.out.println(arrayList);
//第一次执行,删除失败,因为remove里是用两者的地址进行比较,要在Teacher中重写equals方法
}
}
class Teacher {
private String name;
private Integer age;
public Teacher(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {return true;}//如果地址相同返回true
if (o == null || getClass() != o.getClass()) {return false;}
Teacher teacher = (Teacher) o;
return Objects.equals(name, teacher.name) && Objects.equals(age, teacher.age);
}
}
Vector
(了解,基本不用)
/*
* @Author:
* time 2021.6.2
* */
import javax.xml.bind.Element;
import java.util.Enumeration;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
// 创建Vector集合
Vector vector = new Vector();
// 添加元素
vector.add("1");
vector.add("空姐");
vector.add("护士");
vector.add("警花");
vector.add("5");
System.out.println(vector);
System.out.println(vector.size());//大小
System.out.println("=====================");
// 删除元素
/* vector.remove(1);//通过下标删除
vector.remove("护士");//通过对象删除
vector.clear();//全部删除*/
/* 遍历元素---在JDK1.2 之前使用枚举器,vector 使用枚举器*/
Enumeration elements = vector.elements();
while (elements.hasMoreElements()){
String o = (String) elements.nextElement();//根据类型判断是否强转
System.out.println(o);
}
//判断
System.out.println(vector.contains("教师"));
System.out.println(vector.isEmpty());
System.out.println("==========================");
//其他方法
System.out.println(vector.firstElement());//输出第一个元素
System.out.println(vector.lastElement());//输出最后一个元素
System.out.println(vector.get(2));//输出该下标的元素
System.out.println(vector.elementAt(3));
}
}
结果:
LinkedList
注意他的结构为双向链表 (最好再看一下数据结构)
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
//定义LinkedList
LinkedList list = new LinkedList();
//添加元素 注意Teacher已在上个类里定义
Teacher t1 = new Teacher("苍老师", 30);
Teacher t2 = new Teacher("三上老师", 30);
Teacher t3 = new Teacher("泷泽老师", 30);
list.add(t1);
list.add(t2);
list.add(t3);
list.add(t3);
System.out.println(list);
System.out.println("个数:"+list.size());
System.out.println(list.toString());
System.out.println("============");
//删除元素
list.remove(t3);
System.out.println(list);
System.out.println("============");
System.out.println(list.remove(new Teacher("泷泽老师", 30)));//注意 我们这的equals方法已经被重写了
System.out.println(list);
//元素遍历(与前面相同)
//for
//增强for
//迭代器
//列表迭代器
//判断
System.out.println(list.indexOf(new Teacher("三上老师", 30)));//查询元素下标 //注意 我们这的equals方法已经被重写了
}
}
结果:
ArrayList和LinkedList 区别
ArrayList数组结构实现,必须开辟连续的空间,查询快,增删慢;
LinkedList 链表结构实现,无需开辟连续的空间,查询慢,增删快
Set 接口
Set接口特点:无序,没下标,元素不可以重复
set接口的使用 :`
set的方法和List一样,但执行结果不同,set执行结果是无序的
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Set collection = new HashSet();
//2.添加元素
collection.add("儿");
collection.add("童");
collection.add("节");
collection.add("快");
collection.add("乐");
collection.add("!");
System.out.println("元素个数"+collection.size());
System.out.println(collection);
//3.删除元素
collection.remove("!");
System.out.println("删除后元素个数"+collection.size());
System.out.println(collection);
collection.clear();// 删除全部
System.out.println("clear元素个数"+collection.size());
System.out.println(collection);
//重新赋值
collection.add("儿");
collection.add("童");
collection.add("节");
collection.add("快");
collection.add("乐");
collection.add("!");
//4.遍历元素
//4.1增强for循环
System.out.println("==========增强for循环 ===========");
for(Object o:collection){
System.out.println(o);
}
//4.2迭代器iterator
System.out.println("==========迭代器===========");
Iterator iterator=collection.iterator();
//迭代器iterator返回对象为Iterator<>
//有三个方法
/*
hasNext() 判读有没有下个元素
next()读取下个元素
remove()删除当前元素(选用)
*/
while (iterator.hasNext()){
//Object o = iterator.next(); 知道是字符串类型可以强制转换
String object = (String)iterator.next();
System.out.println(object);
iterator.remove();
}
System.out.println("元素个数:"+collection.size());
//判断
collection.add("儿童");
System.out.println(collection.contains("儿童"));//判断包含
System.out.println(collection.contains("少年少女"));
System.out.println(collection.isEmpty());//判断是否为空
collection.clear();
System.out.println(collection.isEmpty());
}
}
结果
Set实现类
HashSet
存储结构:哈希表
-
基于Hashcode计算元素存放位置
-
当存入元素的哈希码相同时,会调用equals方法进行确认,若结果相同则拒绝后者存入
-
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
-
HashSet 允许有 null 值。
-
HashSet 是无序的,即不会记录插入的顺序。
-
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
-
HashSet 实现了 Set 接口。
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<String>();
hashSet.add("1");
hashSet.add("2");
hashSet.add("3");
hashSet.add("4");
hashSet.add("5");
hashSet.add("3");//注意 添加了兩個 3 未添加成功 -----不重複
System.out.println(hashSet);
//4.遍历元素
//4.1增强for循环
System.out.println("==========增强for循环 ===========");
for(Object o:hashSet){
System.out.println(o);
}
//4.2迭代器iterator
System.out.println("==========迭代器===========");
Iterator iterator=hashSet.iterator();
//迭代器iterator返回对象为Iterator<>
//有三个方法
/*
hasNext() 判读有没有下个元素
next()读取下个元素
remove()删除当前元素(选用)
*/
while (iterator.hasNext()){
//Object o = iterator.next(); 知道是字符串类型可以强制转换
String object = (String)iterator.next();
System.out.println(object);
iterator.remove();
}
System.out.println("元素个数:"+hashSet.size());
//判断
hashSet.add("儿童");
System.out.println(hashSet.contains("1"));//判断包含
System.out.println(hashSet.contains("少年少女"));
System.out.println(hashSet.isEmpty());//判断是否为空
hashSet.clear();
System.out.println(hashSet.isEmpty());
}
}
import java.util.HashSet;
public class HashSetdemo {
public static void main(String[] args) {
HashSet<Teacher> teachers = new HashSet<Teacher>();
Teacher t1 = new Teacher("苍老师", 30);
Teacher t2 = new Teacher("三上老师", 30);
Teacher t3 = new Teacher("泷泽老师", 30);
teachers.add(t1);
teachers.add(t2);
teachers.add(t3);
teachers.add(t1);
System.out.println(teachers);
System.out.println("个数:"+teachers.size());
System.out.println(teachers.toString());
System.out.println("============");
//输出可知第二个t1无法添加
teachers.add(new Teacher("苍老师", 30));
System.out.println(teachers);
System.out.println("个数:"+teachers.size());
//这样 却添加上了相同的元素(地址不同)-----如何使其只能添加不同元素-------解决方法在Teacher类重写hashCode方法
// 使用hashcode计算保存位置,如位置为空,则直接保存,不为空执行第二步
// 执行equals方法,如果equals为true,则认为是重复,否则形成链表
}
}
TreeSet
- 基于排序顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象类型必须实现Comparable接口,确定排序规则
- 通过CompareTo方法确定是否为相同元素,如果返回值为0就是重复元素,不添加
- 存储结构红黑树
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(12);
treeSet.add(35);
treeSet.add(68);
System.out.println(treeSet);//输出结果 [12, 35, 68] 不按输入数据排序但会对集合元素进行排序
System.out.println(treeSet.size());
// treeSet.remove(12);
// treeSet.clear();
//遍历 for 增强for 迭代器
System.out.println(treeSet.contains(12));
System.out.println(treeSet.isEmpty());
System.out.println("=======================");
TreeSet<Person> list = new TreeSet();
/*TreeSet<Person> list = new TreeSet(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1 =o1.getName().compareTo(o2.getName());
int n2 =o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});*/
Person t1 = new Person("苍老师", 30);
Person t2 = new Person("三上老师", 30);
Person t3 = new Person("泷泽老师", 30);
list.add(t1);
list.add(t2);
list.add(t3);
System.out.println(list.toString());
System.out.println(list.size());
}
}
//注意:要想实现用TreeSet红黑树存储对象元素,要使对象类继承Comparable接口,当然,也可在new中创建匿名内部类实现Compare方法
class Person implements Comparable<Person>{
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
}
Map集合体系
特点:存储键值对(Key-Value)
Key:无序,无下标,不允许重复(唯一)
value:无序,无下标,允许重复
void clear()
从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
V get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int hashCode()
返回此映射的哈希码值。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
Set< K> keySet()
返回此映射中包含的键的 Set 视图。
V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int size()
返回此映射中的键-值映射关系数。
Collection values()
返回此映射中包含的值的 Collection 视图。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>() ;
map.put("nmd", "美国导弹防御系统");
map.put("cnmd", "中国导弹防御系统");
map.put("rnmd", "俄国导弹防御系统");
System.out.println(map.size());
System.out.println(map);
//遍历
//使用ketSet方法
System.out.println("========使用ketSet方法=======");
Set<String> set =map.keySet();
for (String a:set){
System.out.println(a+map.get(a));
}
//使用entrySet
System.out.println("========使用entrySet方法=======");
Set<Map.Entry<String,String>> entrySet= map.entrySet();
for (Map.Entry a:entrySet){
System.out.println(a.getKey()+"=============="+a.getValue());
}
//判断
map.containsKey("nmd");//是否包含key值nmd
map.containsValue("中国导弹防御系统");//是否包含Value值中国导弹防御系统
}
}
Map实现类
HashMap:JDK1.8 运行比较快,线程不安全;允许使用null作为Key或Value;一般其构造方法的默认容量为16,加载因子为0.75.
TreeMap:实现了Map接口的子接口SortedMap,可以对key自动排序。
HashMap
默认初始容量大小 16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
最大容量 2的30次方
static final int MAXIMUM_CAPACITY = 1 << 30;
默认加载因子 0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f;
Jdk1.8 加入 表示当有数祖上的 链表大于8且数组长度大于等于64,就会将该链表变为红黑树,以增强查询效率
static final int TREEIFY_THRESHOLD = 8;
static final int MIN_TREEIFY_CAPACITY = 64;
指链表长度小于6,又将红黑树调整为链表
static final int UNTREEIFY_THRESHOLD = 6;
刚创建的HashMap对象 size=0, table =null
(1)HashMap创建时,table是null,为了节省空间, 当添加第一个元素时,table容量调称为16
(2)当元素个数大于阙值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数,
(3)jdk1.8当每个链表长度大于8,并且数组元素个数大手等于64时。会调整为红照树,目的提高执行效事
(4)jdk1.8链表长度小于6时,调整成链表
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
//创建HashMap集合
HashMap<Student,String> map = new HashMap<Student,String>();
Student s1 =new Student(100, "Tom");
Student s2 =new Student(101, "Jerry");
Student s3 =new Student(102, "Speike");
//存入元素
map.put(s1,"猫");
map.put(s2,"老鼠");
map.put(s3,"狗");
map.put(s3,"狗大户");
System.out.println(map);//结果为{Student{name='Tom', id=100}=猫, Student{name='Speike', id=102}=狗大户, Student{name='Jerry', id=101}=老鼠}
//若key相同,不是添加是修改value
map.put(new Student(102, "Speike"),"狗大户");
System.out.println(map.size());//第一次执行 4 相同的被添加进去 因为map记录的是地址 ,不是记录数据,重new相当于新建一个地址存储
//去除此种重复,要重写Student的hashCode和equals方法
//删除元素
map.remove(s3);
System.out.println("删除后个数:"+map.size());
System.out.println(map.toString());
//遍历
//使用ketSet方法
System.out.println("========使用ketSet方法=======");
Set<Student> set =map.keySet();
for (Student a:set){
System.out.println(a+map.get(a));
}
//使用entrySet
System.out.println("========使用entrySet方法=======");
Set<Map.Entry<Student,String>> entrySet= map.entrySet();
for (Map.Entry a:entrySet){
System.out.println(a.getKey()+"=============="+a.getValue());
}
}
}
class Student{
private String name;
private Integer id;
public Student( Integer id,String name) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) {return true;}
if (o == null || getClass() != o.getClass()) {return false;}
Student student = (Student) o;
return Objects.equals(name, student.name) && Objects.equals(id, student.id);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
结果:
HashTable(了解)
HashMap:JDK1.8 运行比较快,线程不安全;允许使用null作为Key或Value;
Hashtable:JDK1.0 运行较慢,线程安全,不允许null作为Key或Value;
Properties:Hashtable的子类,要求key和value都为String,通常用于配置文件的读取。
TreeMap
import java.util.TreeMap;
public class TreeMapTest {
public static void main(String[] args) {
//创建HashMap集合
TreeMap<Student,String> map = new TreeMap<Student,String>();
Student s1 =new Student(100, "Tom");
Student s2 =new Student(101, "Jerry");
Student s3 =new Student(102, "Speike");
//存入元素
map.put(s1,"猫");
map.put(s2,"老鼠");
map.put(s3,"狗");
map.put(s3,"狗大户");
System.out.println(map.size());
System.out.println(map);
}
}
直接运行,我们会发现
因为存储为红黑树,要排序,要给对象定义排序规则:
class Student implements Comparable<Student>{
private String name;
private Integer id;
public Student( Integer id,String name) {
this.name = name;
this.id = id;
}
@Override
public int compareTo(Student o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.id-o.getId();
return n1==0?n2:n1;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) {return true;}
if (o == null || getClass() != o.getClass()) {return false;}
Student student = (Student) o;
return Objects.equals(name, student.name) && Objects.equals(id, student.id);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
再次运行:
也可以用匿名内部类定义排序规则
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeMap;
public class TreeMapTest {
public static void main(String[] args) {
//创建HashMap集合
//利用匿名内部类实现排序规则的定义
TreeMap<Student,String> map = new TreeMap<Student,String>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1 = o1.getName().compareTo(o2.getName());
int n2 = o1.getId()-o2.getId();
return n1==0?n2:n1;
}
});
Student s1 =new Student(100, "Tom");
Student s2 =new Student(101, "Jerry");
Student s3 =new Student(102, "Speike");
//存入元素
map.put(s1,"猫");
map.put(s2,"老鼠");
map.put(s3,"狗");
map.put(s3,"狗大户");
System.out.println(map.size());
System.out.println(map);
//这次不会在创建新的 因为我们的Student方法重写了HashCode和equals方法
map.put(new Student(102, "Speike"),"狗");
System.out.println(map.size());
System.out.println(map);
//删除元素
map.remove(s3);
//判断
System.out.println(map.containsKey(s2));
System.out.println(map.containsValue("猫"));
}
}
结果:
Collections工具类
集合工具类,定义了除存取以外的集合常用方法。
具体使用查看API文档中的方法
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(12);
arrayList.add(6);
arrayList.add(16);
arrayList.add(52);
//排序sort
System.out.println(arrayList);
Collections.sort(arrayList);
System.out.println(arrayList);
//二分查找法 binarySearch
int i = Collections.binarySearch(arrayList, 6);//找到返回大于等于0的数,没找到返回-1
System.out.println(i);
//copy 复制
List list = new ArrayList();
for (int j = 0; j <arrayList.size() ; j++) {
list.add(0);
}
Collections.copy(list, arrayList);//注意list的容量大于等于arrayList才能添加成功
System.out.println(list);
//reverse 反转 list现在由从小到大变为从大到小
Collections.reverse(list);
System.out.println(list);
//shuffle打乱
Collections.shuffle(list);
System.out.println(list);
//list转为数组
Object[] a = arrayList.toArray();
System.out.println(a.length);
System.out.println(a);
System.out.println(Arrays.toString(a));
//数组转为集合
String[] name = {"1","2,","3"};
List<String> l= Arrays.asList(name);
//转化成的集合是一个受限制集合,不能添加和删除
//将基本类型数组,转化为结合要修改为包装类
System.out.println(l);
}
}