集合
- 对象的容器
- 定义了对多个对象进行操作的常用方法
- 类似数组的功能
集合和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型(集合想存储基本类型数据,可以把基本类型进行装箱操作)
Collection体系集合
List接口
- 有序
- 有下标
- 元素可重复
Set接口
- 无序
- 无下标
- 元素不能重复
Collection接口
整体上可把Collection看做无序,无下标,不能重复
- add() 把一个对象添加到集合中
- addAll() 将一个集合中的所有对象添加到此集合中
- clear() 清空此集合中的所有对象
- contains() 检查此集合中是否包含某个对象
- equals() 比较此集合是否与指定对象相等
- isEmpty() 判断此集合是否为空
- remove() 在此集合中移除某个对象
- size() 获取集合中的元素个数
- toArray() 将此集合转成数组
- iterator()
例子
package com.qf.chapter12_1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//Collection接口的使用
/*
* 添加元素
* 删除元素
* 遍历元素
* 判断
*
*/
public class Demo1 {
public static void main(String[] args) {
//创建一个集合
Collection collection = new ArrayList();
//添加元素
collection.add("苹果");//字符串是引用类型
collection.add("西瓜");
collection.add("榴莲");
System.out.println("元素个数:" + collection.size());
System.out.println(collection);
//删除元素
collection.remove("榴莲");
//collection.clear();//清空
System.out.println("删除后:" + collection.size());
System.out.println(collection);
System.out.println("-----------------------");
//遍历【重点】
//第一种方式:使用增强for循环
for (Object object : collection) {
System.out.println(object);
}
System.out.println("-----------------------");
//第二种方式:使用迭代器(专门用来遍历集合的一种方式)
//iterator()
Iterator it = collection.iterator();
//Iterator这个接口中有三个方法:
//hasNext() 有没有下一个元素
//next() 获取下一个元素
//remove() 删除当前元素
while(it.hasNext()) {
String next = (String) it.next();
System.out.println(next);
//在迭代的过程中,不能使用Collection的remove()方法
//但可以使用Iterator的remove()方法
it.remove();
}
System.out.println("删除后:" + collection.size());
//判断
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty());
}
}
例子
package com.qf.chapter12_1;
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
package com.qf.chapter12_1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* Collection的使用:保存学生信息
*/
public class Demo2 {
public static void main(String[] args) {
//先新建Collection对象
Collection collection = new ArrayList();
Student s1 = new Student("张三",10);
Student s2 = new Student("张无忌",18);
Student s3 = new Student("王八",43);
//添加学生数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s3);
System.out.println("元素个数:" + collection.size());
System.out.println(collection.toString());
//删除
collection.remove(s1);
//collection.clear();//清除,只是把这三个对象移出集合,并没有删除这三个对象
System.out.println("删除后:" + collection.size());
System.out.println(collection.toString());
//遍历
for (Object object : collection) {
Student s = (Student) object;
System.out.println(s.toString());
}
Iterator it = collection.iterator();
while(it.hasNext()) {
Student next = (Student) it.next();
System.out.println(next.toString());
}
//判断
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
List子接口
-
有序
-
有下标
-
元素可重复
-
add() 可以指定位置插入
-
addAll() 可以指定位置
-
get() 可以获取指定位置元素
-
subList() 可以把集合中的某一部分获取到,得到一个子集合
-
listIterator()
例子
package com.qf.chapter12_1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
* List子接口的使用
* 有序有下标可重复
*
*/
public class Demo3 {
public static void main(String[] args) {
//先创建集合对象
List list = new ArrayList();
//添加元素
list.add("苹果");
list.add("小米");
list.add(0,"华为");
System.out.println("元素个数:" + list.size());
System.out.println(list.toString());
//删除元素
//list.remove("苹果");
list.remove(0);
System.out.println("删除后:" + list.size());
System.out.println(list.toString());
//遍历操作【重点】
//1、for遍历,因为它有下标
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//2、增强for
for (Object object : list) {
System.out.println(object);
}
//3、迭代器
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//4、使用列表迭代器,功能更强大
ListIterator listIt = list.listIterator();
while (listIt.hasNext()) {
System.out.println(listIt.nextIndex());
System.out.println(listIt.next());
}
//从后往前,基于刚才的迭代,指针已经指向集合的最后一个元素
while(listIt.hasPrevious()) {
System.out.println(listIt.previous());
}
//判断
System.out.println(list.contains("小米"));
System.out.println(list.isEmpty());
//获取元素位置
System.out.println(list.indexOf("苹果"));
}
}
例子
package com.qf.chapter12_1;
import java.util.ArrayList;
import java.util.List;
/*
*
* List的使用
*
*
*/
public class Demo {
public static void main(String[] args) {
//创建集合
List list = new ArrayList();
//添加数据
list.add(20);//添加数字的时候,隐含了一个自动装箱操作
list.add(30);//因为集合是不能添加基本类型的
list.add(40);
list.add(50);
list.add(60);
System.out.println("元素个数:" + list.size());
System.out.println(list.toString());
//删除操作
//删除20
//list.remove(0);
//list.remove((Object)20);
list.remove(new Integer(20));
System.out.println("删除后:" + list.size());
System.out.println(list.toString());
//subList()
List subList = list.subList(1, 3);//包含1不包含3
System.out.println(subList.toString());
}
}
List实现类
- ArrayList 【重点】
- 数组结构实现
- 查询快
- 增删慢
- 运行效率快,线程不安全
- Vector
- 数组结构实现
- 查询快
- 增删慢
- 运行效率慢,线程安全
- LinkedList 【重点】
- 链表结构实现
- 增删快
- 查询慢
ArrayList
源码分析
-
默认容量大小 DEFAULT_CAPACITY = 10
- 注意:如果没有向集合中添加任何元素时,它的容量是0
- 当添加第一个元素时,容量才为10。之后自动扩容,每次扩容为原来的1.5倍
-
存放元素的数组 elementData
-
实际元素个数 size
例子
package com.qf.chapter12_1;
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
//判断是不是同一个对象
if(this==obj) {
return true;
}
//判断是否为空
if(obj==null) {
return false;
}
//判断是否是Student类型
if(obj instanceof Student) {
Student stu = (Student) obj;
//比较属性
if(this.name.equals(stu.getName()) && this.age==stu.getAge()) {
return true;
}
}
return false;
}
}
package com.qf.chapter12_1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/*
* ArrayList的使用
*
*/
public class Demo5 {
public static void main(String[] args) {
//创建一个集合
ArrayList arrayList = new ArrayList();
//添加元素
Student s1 = new Student("刘德华",20);
Student s2 = new Student("郭富城",22);
Student s3 = new Student("梁朝伟",18);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println("元素个数:" + arrayList.size());
System.out.println(arrayList.toString());
//删除元素
//arrayList.remove(s1);
arrayList.remove(new Student("刘德华",20));//equals方法重写了
System.out.println("删除后:" + arrayList.size());
System.out.println(arrayList.toString());
//遍历元素【重点】
//1、迭代器
Iterator it = arrayList.iterator();
while(it.hasNext()) {
Student next = (Student) it.next();
System.out.println(next.toString());//加不加toString都一样
}
//2、列表迭代器
ListIterator listIt= arrayList.listIterator();
while(listIt.hasNext()) {
Student next = (Student) listIt.next();
System.out.println(next.toString());//加不加toString都一样
}
while(listIt.hasPrevious()) {
Student previous = (Student) listIt.previous();
System.out.println(previous);
}
//判断
System.out.println(arrayList.contains(s2));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(s3));
}
}
Vector
例子
package com.qf.chapter12_2;
import java.util.Enumeration;
import java.util.Vector;
/*
* 演示Vector集合的使用
*/
public class Demo1 {
public static void main(String[] args) {
//创建集合
Vector vector = new Vector();
//添加元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素个数:" + vector.size());
//删除操作,参考之前讲的
//vector.remove(0);
//遍历
//Vector的特有方法:使用枚举器
Enumeration en = vector.elements();
while(en.hasMoreElements()) {
String nextElement = (String) en.nextElement();
System.out.println(nextElement);
}
//判断
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
//其它方法
//firstElement() lastElement() elementAt()
}
}
LinkedList
例子
package com.qf.chapter12_2;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import com.qf.chapter12_1.Student;
/*
* LinkedList的使用
* 存储结构:双向链表
*
*/
public class Demo2 {
public static void main(String[] args) {
//创建对象
LinkedList linkedList = new LinkedList();
//添加元素
Student s1 = new Student("刘德华",20);
Student s2 = new Student("郭富城",22);
Student s3 = new Student("梁朝伟",18);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println("元素个数:" + linkedList.size());
System.out.println(linkedList.toString());
//删除
linkedList.remove(s1);
System.out.println("删除后:" + linkedList.size());
//linkedList.clear();
//遍历
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
for (Object object : linkedList) {
Student s = (Student) object;
System.out.println(s.toString());
}
Iterator iterator = linkedList.iterator();
while(iterator.hasNext()) {
Student next = (Student) iterator.next();
System.out.println(next.toString());
}
ListIterator listIterator = linkedList.listIterator();
while(listIterator.hasNext()) {
Student next = (Student) listIterator.next();
System.out.println(next.toString());
}
//判断
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
//获取
System.out.println(linkedList.indexOf(s3));
}
}
Student类代码参考上面的
泛型
Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型(只能是引用类型)作为参数传递
常见形式
- 泛型类
- 泛型接口
- 泛型方法
语法
- <T,…> T称为类型占位符,表示一种引用类型
泛型的好处
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
不同的泛型类型对象之间不能相互赋值
泛型类
例子
package com.qf.chapter12_2;
/*
* 泛型类
* 语法:类型<T,E,....>
* T表示类型占位符,表示一种引用类型,如果编写多个,使用逗号隔开
*
*/
public class MyGeneric<T> {
//使用泛型T
//1、创建变量
T t;//可以创建变量,但不能直接new一个对象,因为T还不确定,构造方法还不确定
//2、作为方法的参数
public void show(T t) {
System.out.println(t);
}
//3、使用泛型作为方法返回值
public T getT() {
return t;
}
}
package com.qf.chapter12_2;
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类来创建对象
//此时要用一个实际的引用类型去填类型占位符T
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t = "hello";
myGeneric.show("大家好");
System.out.println(myGeneric.getT());
MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
myGeneric2.t = 199;
myGeneric2.show(200);
Integer t = myGeneric2.getT();
System.out.println(t);
}
}
泛型接口
例子
package com.qf.chapter12_2;
/*
* 泛型接口
* 语法:接口名<T>
* 注意:不能使用泛型创建静态常量
*/
public interface MyInterface<T> {
String name = "张三";
T server(T t);
}
package com.qf.chapter12_2;
//第一种方式在实现泛型接口的时候,把泛型传给他
public class MyInterfaceImpl implements MyInterface<String>{
@Override
public String server(String t) {
System.out.println(t);
return t;
}
}
package com.qf.chapter12_2;
//第二种方式
//前一个T是泛型类的泛型参数,后一个T是泛型接口的泛型参数
//两个T的类型保持一致
public class MyInterfaceImpl2<T> implements MyInterface<T>{
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
package com.qf.chapter12_2;
public class TestGeneric {
public static void main(String[] args) {
MyInterfaceImpl myInterfaceImpl = new MyInterfaceImpl();
myInterfaceImpl.server("哈哈哈");
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
impl2.server(1000);
}
}
泛型方法
例子
package com.qf.chapter12_2;
/*
* 泛型方法
* 语法:<T> 返回值类型
*/
public class MyGenericMethod {
//泛型方法
public <T> T show(T t) {
System.out.println("泛型方法" + t);
return t;
}
}
package com.qf.chapter12_2;
public class TestGeneric {
public static void main(String[] args) {
//泛型方法
MyGenericMethod mgm = new MyGenericMethod();
//T的泛型类型会根据传递的参数类型自动决定
mgm.show("中国加油");
mgm.show(200);
mgm.show(2.89);
}
}
泛型集合
泛型集合也可称为参数化类型、类型安全的结合,强制集合元素的类型必须一致
特点
- 编译时即可检查,而非运行时抛出异常
- 访问时,不必类型转换
- 不同泛型之间引用不能相互赋值,泛型不存在多态
例子
package com.qf.chapter12_2;
import java.util.ArrayList;
import java.util.Iterator;
import com.qf.chapter12_1.Student;
public class Demo3 {
public static void main(String[] args) {
/*
ArrayList arrayList = new ArrayList();
arrayList.add("xxx");
arrayList.add("yyy");
arrayList.add(20);
arrayList.add(10);
for (Object object : arrayList) {
String str = (String)object;
//这里会报错,这里可以用泛型集合来避免类型转换的异常
System.out.println(str);
}*/
//这里在创建集合对象的时候已经确定了集合里面的类型
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("xxx");
arrayList.add("yyy");
for (String string : arrayList) {
System.out.println(string);
}
ArrayList<Student> arrayList2 = new ArrayList<Student>();
Student s1 = new Student("刘德华",20);
Student s2 = new Student("郭富城",22);
Student s3 = new Student("梁朝伟",18);
arrayList2.add(s1);
arrayList2.add(s2);
arrayList2.add(s3);
//这个迭代器也是一个泛型
Iterator<Student> it = arrayList2.iterator();
while(it.hasNext()) {
Student next = it.next();
System.out.println(next);//toString加不加都一样
}
}
}
Set子接口
方法:全部继承自Collection
- 无序
- 无下标
- 不重复
Set的实现类
- HashSet【重点】
- 基于HashCode实现元素不重复
- 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
- TreeSet
- 基于排列顺序实现元素不重复
例子
package com.qf.chapter12_3;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
* 测试Set接口的使用
*
*/
public class Demo1 {
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet();
//添加数据
set.add("小米");
set.add("苹果");
set.add("华为");
set.add("华为");//重复不会继续添加
System.out.println("数据个数:" + set.size());
System.out.println(set);
//删除
//set.remove("小米");
//System.out.println(set);
//遍历【重点】
//1、增强for
for (String string : set) {
System.out.println(string);
}
//2、迭代器
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(set.contains("华为"));
System.out.println(set.isEmpty());
}
}
HashSet
- 存储结构:哈希表(可以理解为数组+链表+红黑树(JDK1.8后才有))
例子
package com.qf.chapter12_3;
import java.util.HashSet;
import java.util.Iterator;
/*
* HashSet集合的使用
* 存储结构:哈希表(可以理解为数组+链表+红黑树(JDK1.8后才有))
*/
public class Demo2 {
public static void main(String[] args) {
//新建集合
HashSet<String> hashSet = new HashSet<String>();
//添加元素
hashSet.add("刘德华");
hashSet.add("梁朝伟");
hashSet.add("林志玲");
hashSet.add("周润发");
hashSet.add("周润发");//重复不添加
System.out.println("元素个数:" + hashSet.size());
System.out.println(hashSet);
//删除数据
//hashSet.remove("刘德华");
//System.out.println("删除后:" + hashSet.size());
//遍历
for (String string : hashSet) {
System.out.println(string);
}
Iterator<String> iterator = hashSet.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(hashSet.contains("周润发"));
System.out.println(hashSet.isEmpty());
}
}
例子
package com.qf.chapter12_3;
public class Person {
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
//快速重写这两个方法 alt+shift+s 选择对应的重写
@Override
public int hashCode() {
//为什么是31呢
//31是质数,减少散列冲突
//可以提高执行效率 31*i=(i<<5)-i
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//如果每次都重写这两个方法,太麻烦了
// @Override
// public int hashCode() {
// int n1 = this.name.hashCode();
// int n2 = this.age;
// return n1+n2;
// }
//
// @Override
// public boolean equals(Object obj) {
// if(this==obj) {
// return true;
// }
// if(obj==null) {
// return false;
// }
// if(obj instanceof Person) {
// Person p = (Person) obj;
//
// if(this.name.equals(p.getName())&&this.age==p.getAge()) {
// return true;
// }
// }
// return false;
// }
}
package com.qf.chapter12_3;
import java.util.HashSet;
import java.util.Iterator;
/*
* 使用HashSet
*
* 存储过程:(即重复的依据)
* 1、根据hashcode计算保存的位置,如果此位置为空则直接保存,如果不为空则执行第二步
* 2、再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
public class Demo3 {
public static void main(String[] args) {
//创建集合
HashSet<Person> persons = new HashSet<Person>();
//添加数据
Person p1 = new Person("刘德华",20);
Person p2 = new Person("周杰伦",18);
Person p3 = new Person("郭富城",32);
persons.add(p1);
persons.add(p2);
persons.add(p3);
//persons.add(p3);//重复不添加
//重写了hashcode和equals方法,所以不能放进来
persons.add(new Person("郭富城",32));
System.out.println(persons.size());
System.out.println(persons);
//删除数据
//persons.remove(p1);
//persons.remove(new Person("周杰伦",18));
//System.out.println(persons.size());
//System.out.println(persons);
//遍历
for (Person person : persons) {
System.out.println(person);
}
Iterator<Person> iterator = persons.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(persons.contains(p2));
}
}
TreeSet
-
存储结构:红黑树(在二叉查找树的基础上,根节点和叶子节点为黑色)
-
基于排列顺序实现元素不重复
-
实现了SortedSet接口,对集合元素自动排序
-
元素对象的类型必须实现Comparable接口,指定排序规则
-
通过CompareTo方法确定是否为重复元素
例子
package com.qf.chapter12_3;
import java.util.Iterator;
import java.util.TreeSet;
/*
* TreeSet的使用
* 存储结构:红黑树
*/
public class Demo4 {
public static void main(String[] args) {
//创建一个集合
TreeSet<String> treeSet = new TreeSet<String>();
//添加元素
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");
treeSet.add("xyz");//重复不添加
System.out.println("元素个数:" + treeSet.size());
System.out.println(treeSet);
//删除元素
//treeSet.remove("xyz");
//System.out.println("删除后:" + treeSet.size());
//遍历
//增强for
for (String string : treeSet) {
System.out.println(string);
}
Iterator<String> iterator = treeSet.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(treeSet.contains("abc"));
}
}
例子
package com.qf.chapter12_3;
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
//先按姓名比较
//然后再按年龄比较
//compareTo方法返回值为0则认为是重复元素
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
}
package com.qf.chapter12_3;
import java.util.Iterator;
import java.util.TreeSet;
/*
* TreeSet
*/
public class Demo5 {
public static void main(String[] args) {
//创建集合
TreeSet<Person> persons = new TreeSet<Person>();
//添加元素
Person p1 = new Person("xyz",20);
Person p2 = new Person("hello",18);
Person p3 = new Person("zhangsan",32);
Person p4 = new Person("zhangsan",44);
//要求:元素必须要实现Comparable接口,重写compareTo方法
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println("元素个数:" + persons.size());
System.out.println(persons);
//删除
//persons.remove(p1);
//System.out.println("删除后:" + persons.size());
//遍历
//增强for
for (Person person : persons) {
System.out.println(person);
}
//迭代器
Iterator<Person> iterator = persons.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(persons.contains(new Person("zhangsan",44)));
}
}
- Comparator 接口
package com.qf.chapter12_3;
import java.util.Comparator;
import java.util.TreeSet;
/*
* TreeSet集合的使用
* Comparator:实现定制比较(比较器)
* Comparable:可比较的
*/
public class Demo6 {
public static void main(String[] args) {
//创建集合,并指定比较规则
TreeSet<Person> persons = new TreeSet<Person>(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",20);
Person p2 = new Person("hello",18);
Person p3 = new Person("zhangsan",32);
Person p4 = new Person("lisi",32);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println(persons.toString());
}
}
- TreeSet案例
package com.qf.chapter12_3;
import java.util.Comparator;
import java.util.TreeSet;
/*
* 要求:使用TreeSet集合实现字符串按照长度进行排序
* Comparator接口实现定制比较
*/
public class Demo7 {
public static void main(String[] args) {
//创建结合,并指定比较规则
TreeSet<String> treeSet = new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
//添加数据
treeSet.add("helloworld");
treeSet.add("pingguo");
treeSet.add("lisi");
treeSet.add("zhangsan");
treeSet.add("beijing");
treeSet.add("cat");
treeSet.add("nanjing");
treeSet.add("xian");
System.out.println(treeSet);
}
}
Map集合
Map接口的特点
-
用于存储任意键值对(Key-Value)
-
键:无序、无下标、不允许重复(唯一)
-
值:无序、无下标、允许重复
-
put()
-
get()
-
entrySet()
-
keySet()
-
values()
例子
package com.qf.chapter12_4;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/*
*
* Map接口的使用
* 特点:存储键值对;键不重复,值可以重复;无序
*
*/
public class Demo1 {
public static void main(String[] args) {
//创建Map集合
//Map<K,V>
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put("cn", "中国");
map.put("uk", "英国");
map.put("usa", "美国");
map.put("cn", "zhongguo");//把前面的value替换了
System.out.println("元素个数:" + map.size());
System.out.println(map.toString());
//删除
map.remove("usa");
System.out.println("删除后:" + map.size());
System.out.println(map.toString());
//遍历【重点】
//1、keySet() 返回的是所有key的set集合
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key + "-" + map.get(key));
}
//2、entrySet() 一个Entry可以理解为一个映射对或键值对
//entrySet()效率高于keySet()
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey() + "-----------" + entry.getValue());
}
//判断
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("英国"));
}
}
HashMap【重点】
- JDK1.2版本 线程不安全,运行效率快;允许用null作为key或是value
- 默认初始容量 16
- 默认加载因子(例如容量为100,当超过75的时候开始扩容) 0.75
package com.qf.chapter12_4;
public class Student {
private String name;
private int stuNO;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int stuNO) {
super();
this.name = name;
this.stuNO = stuNO;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNO() {
return stuNO;
}
public void setStuNO(int stuNO) {
this.stuNO = stuNO;
}
@Override
public String toString() {
return "Student [name=" + name + ", stuNO=" + stuNO + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + stuNO;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (stuNO != other.stuNO)
return false;
return true;
}
}
package com.qf.chapter12_4;
import java.util.HashMap;
import java.util.Map.Entry;
/*
* HashMap集合的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 使用key的hashcode和equals作为重复依据
*/
public class Demo2 {
public static void main(String[] args) {
//创建集合
HashMap<Student,String> students = new HashMap<Student,String>();
//添加元素
Student s1 = new Student("孙悟空",100);
Student s2 = new Student("猪八戒",101);
Student s3 = new Student("沙和尚",102);
students.put(s1, "北京");
students.put(s2, "上海");
students.put(s3, "杭州");
//students.put(s3, "南京");
students.put(new Student("沙和尚",102),"杭州");//重写hascode和equals则不能添加
System.out.println("元素个数:" + students.size());
System.out.println(students);
//删除
students.remove(s1);
System.out.println("删除后:" + students.size());
//遍历
//keySet()
for (Student key : students.keySet()) {
System.out.println(key.toString() + "=====" + students.get(key));
}
//entrySet()
for (Entry<Student, String> entry : students.entrySet()) {
System.out.println(entry.getKey() + "====" + entry.getValue());
}
//判断
System.out.println(students.containsKey(s2));
System.out.println(students.containsValue("杭州"));
}
}
TreeMap
- 实现了SortedMap接口(是Map的子接口),可以对key自动排序
例子
package com.qf.chapter12_4;
public class Student implements Comparable<Student>{
private String name;
private int stuNO;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int stuNO) {
super();
this.name = name;
this.stuNO = stuNO;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNO() {
return stuNO;
}
public void setStuNO(int stuNO) {
this.stuNO = stuNO;
}
@Override
public String toString() {
return "Student [name=" + name + ", stuNO=" + stuNO + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + stuNO;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (stuNO != other.stuNO)
return false;
return true;
}
@Override
public int compareTo(Student o) {
int n2 = this.stuNO-o.getStuNO();
return n2;
}
}
package com.qf.chapter12_4;
import java.util.Map.Entry;
import java.util.TreeMap;
public class Demo3 {
public static void main(String[] args) {
//新建集合,可以定制比较(参考TreeSet)
TreeMap<Student,String> treeMap = new TreeMap<Student,String>();
//添加元素
Student s1 = new Student("孙悟空",100);
Student s2 = new Student("猪八戒",101);
Student s3 = new Student("沙和尚",102);
//元素对象必须实现Comparable接口
treeMap.put(s1, "北京");
treeMap.put(s2, "上海");
treeMap.put(s3, "深圳");
treeMap.put(new Student("沙和尚",102), "南京");//添加失败,不过value替换了
System.out.println("元素个数:" + treeMap.size());
System.out.println(treeMap);
//删除
treeMap.remove(s3);
System.out.println("元素个数:" + treeMap.size());
System.out.println(treeMap);
//遍历
//keySet()
for (Student key : treeMap.keySet()) {
System.out.println(key + "===" + treeMap.get(key));
}
//entrySet()
for (Entry<Student,String> entry : treeMap.entrySet()) {
System.out.println(entry);
//System.out.println(entry.getKey() + "---" + entry.getValue());
}
//判断
System.out.println(treeMap.containsKey(s3));
}
}
Colletions工具类
-
集合工具类(对集合进行操作),定义了除了存取以外的集合常用方法
-
reverse()
-
shuffle()
-
sort()
例子
package com.qf.chapter12_4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Demo4 {
public static void main(String[] args) {
//创建集合
List<Integer> list = new ArrayList<Integer>();
list.add(20);
list.add(5);
list.add(12);
list.add(30);
list.add(6);
//sort() 排序
System.out.println("排序前:" + list.toString());
Collections.sort(list);
System.out.println("排序后:" + list.toString());
//binarySearch() 二分查找的前提先排好序
int i = Collections.binarySearch(list, 20);
System.out.println(i);
//copy() 复制
List<Integer> dest = new ArrayList<Integer>();
for (int j = 0; j < list.size(); j++) {
dest.add(0);
}
Collections.copy(dest, list);
System.out.println(dest);
//reverse() 反转
Collections.reverse(list);
System.out.println("反转后:" + list.toString());
//shuffle() 打乱
Collections.shuffle(list);
System.out.println("打乱后:" + list.toString());
//补充:list转成数组
//list的集合有多长,array数组的长度就有多长
Integer[] array = list.toArray(new Integer[0]);
System.out.println(array.length);
System.out.println(Arrays.toString(array));
//数组转成list
String[] names = {"张三","李四","王五"};
//注意:这个集合是受限集合,不能添加和删除
List<String> asList = Arrays.asList(names);
System.out.println(asList);
//特殊,基本类型数组转成集合时,需要修改为对应的包装类型
Integer[] nums = {100,200,300,400,500};
List<Integer> asList2 = Arrays.asList(nums);
System.out.println(asList2);
}
}