Java集合类
一、集合的引入
(1)创建一个对象数组对象数组:可以存储对象的数组
public class ClarrayDemo {
public static void main(String[] args) {
//创建一个学生对象数组,指定长度为3;
Student[] arrs=new Student[3];
//创建三个学生对象
Student s1=new Student("刘备",27);
Student s2=new Student("关羽",27);
Student s3=new Student("张飞",26);
//将对象存入对象数组
arrs[0]=s1;
arrs[1]=s2;
arrs[2]=s3;
//遍历对象数组
for(int x=0;x<arrs.length;x++) {
System.out.println(arrs[x].toString());
}
}
}
//创建一个Student类
public class Student {
//成员变量姓名和年龄
private String name;
private int age;
public Student() {
super();
}
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;
}
//重写toString()方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "name:"+name+"----------"+"age:"+age;
}
}
显示:
name:刘备----------age:27
name:关羽----------age:27
name:张飞----------age:26
由以上程序可以看出,对象数组在存储对象时必须规定好长度,而后要添加新的对象时
则需要修改长度,集合就很好的解决这些问题。
二、集合
集合与数组类似,Java提供集合类的主要目的在于“保存多个数据/对象”,提供一种比数组下标存取方式更灵活的方法。
数组和集合的区别?
1)长度区别:
数组长度固定
集合长度可变
2)内容的区别
数组可以存储同一种类型的元素
集合可以存储多种类型的元素
3)存储类型的区别
数组:可以存储基本类型,也可以存储引用类型
集合:只能存储引用类型
三、Collection集合
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:它提供更具体的子接口,更具体的实现类。
基本功能:
添加功能:
boolean add(Object e)//只要添加成功就返回true;
创建集合存储对象
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建集合对象
Collection c=new ArrayList();
//创建学生对象
Student s1=new Student("刘备",27);
Student s2=new Student("关羽",27);
Student s3=new Student("张飞",26);
Student s4=new Student("诸葛",31);
//存入对象
c.add(s1);
c.add(s2);
c.add(s3);
c.add(s4);
//显示输出集合对象
System.out.println(c);
}
}
显示:
[name:刘备----------age:27, name:关羽----------age:27, name:张飞----------age:26, name:诸葛----------age:31]
删除功能:
void clear() :删除集合中所有元素(暴力删除)
boolean remove(Object o):删除集合中的指定元素,删除成功返回true;
判断功能:
boolean contains(Object o):集合中是否包含指定的元素
boolean isEmpty():集合是否为空
获取功能:
int size() :获取集合中的元素数
转换功能:
Object[] toArray() :将集合转换成对象数组
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建集合对象
Collection c=new ArrayList();
//创建学生对象
Student s1=new Student("刘备",27);
Student s2=new Student("关羽",27);
Student s3=new Student("张飞",26);
Student s4=new Student("诸葛",31);
//存入对象
c.add(s1);
c.add(s2);
c.add(s3);
c.add(s4);
//显示输出集合对象
System.out.println(c);
//删除集合中指定的元素
System.out.println("删除s3:"+c.remove(s3));
System.out.println(c);
//判断集合是否包含指定元素
System.out.println("是否包含S3:"+c.contains(s3));
//获取集合长度
System.out.println("长度为:"+c.size());
//删除集合中的全部元素
c.clear();
System.out.println(c);
//判断该集合是否为空
System.out.println("该集合是否为空:"+c.isEmpty);
//重新添加元素,并将集合转换维数组
c.add(s1);
c.add(s2);
Object[] a=c.toArray();
//遍历数组
for(int x = 0; x<a.length;x++) {
System.out.println(a[x]);
}
}
}
显示:
[name:刘备----------age:27, name:关羽----------age:27, name:张飞----------age:26, name:诸葛----------age:31]
删除s3:true
[name:刘备----------age:27, name:关羽----------age:27, name:诸葛----------age:31]
是否包含S3:false
长度为:3
[]
该集合是否为空:true
name:刘备----------age:27
name:关羽----------age:27
高级功能:
添加功能:
boolean addAll(Collection c) :添加一个集合中的所有元素,添加成功返回true
删除功能:
boolean removeAll(Collection c):A集合删除A和与B集合的交集部分,A集合改变返回true
包含功能:
boolean containsAll(Collection c):A集合包含B集合中所有元素返回true,包含部分元素不算包含
交集功能:
boolean retainAll(Collection c):A集合对B集合取交集,相交部分存入A集合(可以为空集),A集合改变返回true
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建一个c1集合并添加元素
Collection c1=new ArrayList();
c1.add("abc1");
c1.add("abc2");
c1.add("abc3");
c1.add("abc4");
//创建一个c2集合并添加元素
Collection c2=new ArrayList();
c2.add("abc1");
c2.add("abc5");
c2.add("abc6");
//创建一个空的c3集合
Collection c3=new ArrayList();
System.out.println("c1="+c1);
System.out.println("c2="+c2);
System.out.println("c3="+c3);
System.out.println("c1添加c2:"+c1.addAll(c2)+" c1="+c1);
System.out.println("c1移除c2:"+c1.removeAll(c2)+" c1="+c1);
System.out.println("c1是否包含c3:"+c1.containsAll(c3)+" c1="+c1);
System.out.println("c1与c2的交集:"+c1.retainAll(c2)+" c1="+c1);
}
}
显示:
c1=[abc1, abc2, abc3, abc4]
c2=[abc1, abc5, abc6]
c3=[]
c1添加c2:true c1=[abc1, abc2, abc3, abc4, abc1, abc5, abc6]
c1移除c2:true c1=[abc2, abc3, abc4] //移除c2中的所有元素,包括重复的元素
c1是否包含c3:true c1=[abc2, abc3, abc4]
c1与c2的交集:true c1=[]
Iterator iterator() :集合的迭代器方法(获取集合的迭代器)
集合的专有遍历方式:迭代器遍历
Iterator 接口中有以下的方法:
boolean hasNext() :是否有下一个可以迭代的元素,如果有元素可以迭代,那么返回true,否则返回false
Object next():返回迭代的下一个元素。
void remove():从迭代器指向的 collection 中移除当前元素
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import Clarray.Student;//自己创建一个学生类导包
public class IteratorDemo {
public static void main(String[] args) {
Collection c1=new ArrayList();
Student s1=new Student("赵云",23);
Student s2=new Student("马超",26);
Student s3=new Student("吕布",28);
Student s4=new Student("周瑜",24);
c1.add(s1);
c1.add(s2);
c1.add(s3);
c1.add(s4);
//创建迭代器对象
Iterator it = c1.iterator(); //快捷键 Ctrl+1
//迭代器遍历
while(it.hasNext()) {
Student s=(Student)it.next();//获取当前元素,并进行强制类型转换
System.out.println(s.getName());
it.remove();//删除当前元素
}
System.out.println(it.hasNext());//是否有下一个可迭代的元素
}
}
显示:
赵云
马超
吕布
周瑜
false
四、List集合
list接口是有序的(输入输出顺序一致)Colletion,使用此接口能够精确地控制每个元素插入的位置,可以通过索引来访问list中的元素。list可以包含重复的元素。public class ListDemo2 {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList() ;
//存储重复元素
list.add("hello") ;
list.add("world") ;
list.add("hello") ;
list.add("java") ;
list.add("javaee") ;
list.add("javaee") ;
list.add("android") ;
list.add("android") ;
//遍历
Iterator it = list.iterator() ;
while(it.hasNext()) {
String s = (String)it.next() ;
System.out.println(s);
}
}
}
显示:
hello
world
hello
java
javaee
javaee
android
android
添加功能:
void add(int index,Object element):在指定位置处添加指定元素
获取功能:
Object get(int index):返回列表中指定位置的元素。
删除功能:
Object remove(int index):删除指定位置处的元素
修改功能:
Object set(int index, Object element):用指定元素替换掉指定位置处的元素
public class ListDemo {
public static void main(String[] args) {
//创建List集合对象
List ls=new ArrayList();
//添加元素
ls.add("hello");
ls.add("world");
ls.add("java");
ls.add("java");
ls.add("Java");
//输出
System.out.println(ls);
//在world后添加happy
ls.add(2,"happy");
System.out.println(ls);
//删除Java
ls.remove(5);
System.out.println(ls);
//吧第二个java改为javaee
ls.set(4, "javaee");
System.out.println(ls);
//获取元素hello
System.out.println(ls.get(0));
//可以使用普通for循环对List集合进行遍历
for(int x=0;x<ls.size();x++) {//使用size()方法获取集合长度
String s=(String)ls.get(x);//将集合元素强制转换为对象类型方便使用
System.out.print(s+":"+s.length()+" ");
}
}
}
显示:
[hello, world, java, java, Java]
[hello, world, happy, java, java, Java]
[hello, world, happy, java, java]
[hello, world, happy, java, javaee]
hello
hello:5 world:5 happy:5 java:4 javaee:6
list中特有的迭代功能:
ListIterator listIterator():列表迭代器,ListIterator继承Iterator
ListIterator接口特有方法:
void add(Object obj);将指定的元素插入当前元素后
void set(Object obj);用指定元素替换当前元素
int nestIndex(); 返回下一个元素的下标,若没有下一个元素,返回列表长度
int previousIndex(); 返回上一个元素的下标,若没有上一个元素,返回-1
boolean hasPrevious(); 是否有上一个可以迭代的元素
Object previous(); 获取上一个元素
public class ListIteratorDemo {
public static void main(String[] args) {
//创建列表集合
List ls=new ArrayList();
ls.add("aaa");
ls.add("bbb");
//使用ListIterator进行迭代
ListIterator lor = ls.listIterator();
//获取列表中的第一个元素
lor.next();
//在当前元素后添加新元素
lor.add("ccc");
//获取第二个元素
lor.next();
//用ddd替换掉当前元素
lor.set("ddd");
//System.out.println(lor.next());//没有下一个可迭代的元素,报错java.util.NoSuchElementException
ListIterator lor2 = ls.listIterator();
while(lor2.hasNext()) {
//返回下一个元素的下标
System.out.println(lor2.nextIndex());
System.out.println(lor2.next());
}
//若没有下一个元素则返回列表长度
System.out.println(lor2.nextIndex());
while(lor2.hasPrevious()) {
//返回上一个元素的下标
System.out.println(lor2.previousIndex());
System.out.println(lor2.previous());
}
//若没有上一个元素则返回-1
System.out.println(lor2.previousIndex());
}
}
显示:
0
aaa
1
ccc
2
ddd
3
2
ddd
1
ccc
0
aaa
-1
List集合有三个子实现类:
ArrayList
底层数据结构是数组结构,查询快,增删慢;
从内存角度考虑:线程不安全的,不同步的,执行效率高
LinkedList
底层数据结构式链表结构,查询慢,增删块
从内存角度考虑:线程不安全,不同步,执行效率高
Vector
底层数据结构是数组:查询快,增删慢
线程安全的,同步,执行效率低
(解决线程安全问题,通过同步可以解决,但是效率低了)
五、ArrayList集合
ArrayList是List接口中常用的一个子实现类。Arraylist集合的应用:
public class ArrayListDemo {
public static void main(String[] args) {
//创建一个ArrayList集合对象
ArrayList as=new ArrayList();
//创建学生类对象
Student02 s1=new Student02("丽丽",1204);//提示:自己创建学生类
Student02 s2=new Student02("明明",1208);
Student02 s3=new Student02("美美",1305);
//添加对象元素
as.add(s1);
as.add(s2);
as.add(s3);
//创建迭代器进行遍历
ListIterator li = as.listIterator();
while(li.hasNext()) {
Student02 s=(Student02)li.next();
System.out.println(s.getName()+" 学号:"+s.getSno());
}
}
}
显示:
丽丽 学号:1204
明明 学号:1208
美美 学号:1305
六、Vector集合
Vector类非常类似于ArrayList,但是Vector是同步的,安全性好,比ArrayList的效率低特有功能:
public void addElement(Object obj):将指定的组件添加到此向量的末尾,将集合其大小增加 1。
public Enumeration elements():返回此向量的枚举。
boolean hasMoreElements():测试此枚举是否包含更多的元素。
Object nextElement() :如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
public class VectorDemo {
public static void main(String[] args) {
Vector v=new Vector();
//创建学生类对象
Student02 s1=new Student02("丽丽",1204);//提示:自己创建学生类
Student02 s2=new Student02("明明",1208);
Student02 s3=new Student02("美美",1305);
//添加元素
v.add(s1);
v.add(s2);
v.addElement(s3);
//迭代
Enumeration e= v.elements();
while(e.hasMoreElements()) {
Student02 s=(Student02)e.nextElement();
System.out.println(s.getName());
}
}
}
显示:
丽丽
明明
美美
七、LinkedList集合
LinkedList集合是List 接口的链接列表实现类。实现所有可选的列表操作,并且允许所有元素(包括 null)。
特有功能:
添加功能addFirst(Object e):将指定的元素插入到列表的开头
addLast(object e):将指定的元素添加到列表末尾
获取功能:
getFirst():获取列表第一个元素
getLast():获取列表最后一个元素
删除功能
public Object removeFirst()移除并返回此列表的第一个元素。
public Object removeLast()移除并返回此列表的最后一个元素。
public class LinkedListDemo {
public static void main(String[] args) {
//创建LinkedList集合
LinkedList ls=new LinkedList();
Student02 s1=new Student02("丽丽",1204);//提示:自己创建学生类并重写toString()方法;
Student02 s2=new Student02("明明",1208);
Student02 s3=new Student02("美美",1305);
Student02 s4=new Student02("焕焕",1307);
//添加元素
ls.add(s1);
ls.add(s2);
System.out.println(ls);
//将对象s3添加到第一个位置
ls.addFirst(s3);
System.out.println(ls);
//将对象s4添加到末尾
ls.addLast(s4);
System.out.println(ls);
//获取第一个元素
System.out.println(ls.getFirst());
//获取最后一个元素
System.out.println(ls.getLast());
//删除第一个元素
ls.removeFirst();
//删除末尾元素
ls.removeLast();
System.out.println(ls);
}
}
显示:
[Student02 [name=丽丽, Sno=1204], Student02 [name=明明, Sno=1208]]
[Student02 [name=美美, Sno=1305], Student02 [name=丽丽, Sno=1204], Student02 [name=明明, Sno=1208]]
[Student02 [name=美美, Sno=1305], Student02 [name=丽丽, Sno=1204], Student02 [name=明明, Sno=1208], Student02 [name=焕焕, Sno=1307]]
Student02 [name=美美, Sno=1305]
Student02 [name=焕焕, Sno=1307]
[Student02 [name=丽丽, Sno=1204], Student02 [name=明明, Sno=1208]]
例题
删除集合中的重复元素
(1)String类型元素
方式一:
public class ArrayListTest {
public static void main(String[] args) {
//创建一个集合
ArrayList list = new ArrayList() ;
//添加元素
list.add("hello") ;
list.add("world") ;
list.add("java") ;
list.add("javaee") ;
list.add("hello") ;
list.add("world") ;
list.add("hello") ;
list.add("javaee") ;
list.add("android") ;
list.add("python") ;
list.add("php") ;
list.add("php") ;
//创建一个新的集合
ArrayList newList = new ArrayList() ;
//遍历旧集合
Iterator it = list.iterator() ;
while(it.hasNext()) {
String s = (String) it.next() ;
//判断新集合中是否包含旧集合中的元素
if(!newList.contains(s)) {
newList.add(s) ;
}
}
//遍历新集合
Iterator it2 = newList.iterator() ;
while(it2.hasNext()) {
String s = (String) it2.next() ;
System.out.println(s);
}
}
}
方式二:
public class ArrayListTest2 {
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList array = new ArrayList() ;
//添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
array.add("javaee") ;
array.add("hello") ;
array.add("world") ;
array.add("hello") ;
array.add("javaee") ;
for(int x = 0 ; x < array.size()-1 ; x ++) {
for(int y = x +1 ; y < array.size() ; y ++) {
//判断,前面的索引对应的元素和后面索引对应的元素进行比较,如果相等就干掉后面重复的
if(array.get(x).equals(array.get(y))) {
array.remove(y) ;
y-- ;
}
}
}
//遍历集合
Iterator it = array.iterator() ;
while(it.hasNext()) {
String s = (String) it.next() ;
System.out.println(s);
}
}
}
(2)自定义类型
//自定义一个学生类
public class Student {
private String name ;
private int age ;
public Student() {
super();
}
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;
}
//一定要重写equals()方法,使得两个对象比较的是内容。
@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 (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class ArrayListTest3 {
public static void main(String[] args) {
//创建一个ArrayList集合
ArrayList array = new ArrayList() ;
//创建4个学锁对象
Student s1 = new Student("刘备", 27);
Student s2 = new Student("张飞", 29);
Student s3 = new Student("诸葛亮", 30);
Student s4 = new Student("刘备", 27);
Student s5 = new Student("刘备", 29);
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
array.add(s5) ;
//创建一个新集合
ArrayList newArray = new ArrayList() ;
//遍历旧集合
Iterator it = array.iterator() ;
while(it.hasNext()) {
Student s = (Student)it.next() ;
//判断,新集合中是否包含
if(!newArray.contains(s)) {//contains()源码中会使用equals()方法进行判断
newArray.add(s) ;
}
}
//遍历新集合
Iterator it2 = newArray.iterator() ;
while(it2.hasNext()) {
Student s= (Student)it2.next();
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
八、Set集合
Set集合:不允许元素重复,唯一的(元素可以为null) ,不能保证迭代的顺序恒久不变(底层哈希表和hascode)无序(存储和取出不一致)
public class SetDemo {
public static void main(String[] args) {
//创建Set集合对象,子实现类:HashSet集合
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello") ;
set.add("java") ;
set.add("world") ;
//添加重复元素
set.add("hello") ;
set.add("java") ;
set.add("world") ;
//遍历
for(String s: set) {
System.out.println(s);
}
}
}
显示:
java
world
hello
用Set集合存储自定义对象
public class SetDemo {
public static void main(String[] args) {
Set<Student> t1=new HashSet<Student>();
//创建学生对象
Student s1=new Student("刘1",23);
Student s2=new Student("关2",24);
Student s3=new Student("张3",28);
Student s4=new Student("诸葛4",28);
Student s5=new Student("关2",24);
//添加元素
t1.add(s1);
t1.add(s2);
t1.add(s3);
//添加重复元素
t1.add(s2);
t1.add(s4);
//添加重复对象
t1.add(s5);
//遍历
for(Student x:t1) {
System.out.println(x);
}
}
}
显示:
name:刘1----------age:23
name:诸葛4----------age:28
name:关2----------age:24
name:张3----------age:28
name:关2----------age:24
由上可见有重复的元素!
原因:HashSet集合的add()方法本身依赖于hashCode()和equals()方法,所以要重写这两个方法
//创建一个Student类
public class Student {
//成员变量姓名和年龄
private String name;
private int age;
public Student() {
super();
}
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;
}
//重写toString()方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "name:"+name+"----------"+"age:"+age;
}
//重写hashCode()方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
//重写equals()方法
@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 (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
重写后运行显示:
name:关2----------age:24
name:张3----------age:28
name:刘1----------age:23
name:诸葛4----------age:28
如果在开发中,元素唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合
LinkedHashSet集合:
底层是一种链接列表和哈希表组成
可以保证元素的唯一性,是由哈希表决定的(hashCode()和equals())
可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定
public class LinkedHashSetDemo {
public static void main(String[] args) {
//创建LinkedHashSet集合对象
LinkedHashSet<String> link = new LinkedHashSet<String>() ;
//添加元素
link.add("c") ;
link.add("hello") ;
link.add("java") ;
link.add("world") ;
link.add("world") ;
link.add("world") ;
link.add("java") ;
//增强for遍历
for(String s: link) {
System.out.println(s);
}
}
}
显示:
c
hello
java
world
九、TreeSet集合
TreeSet类是使用树结构存储元素的类集合,对象安升序存储public class SetDemo {
public static void main(String[] args) {
//创建一个集合对象TreeSet集合对象
TreeSet<Integer> ts = new TreeSet<Integer>() ;
//给集合中存储元素
ts.add(20) ;
ts.add(22) ;
ts.add(18) ;
ts.add(23) ;
ts.add(24) ;
ts.add(17) ;
ts.add(19) ;
ts.add(18) ;
ts.add(24) ;
//遍历
for(Integer i : ts) {
System.out.print(i +" ");
}
}
}
显示:
17 18 19 20 22 23 24
import java.util.TreeSet;
public class SetDemo {
public static void main(String[] args) {
//创建一个集合对象TreeSet集合对象
TreeSet<String> ts = new TreeSet<String>() ;
//给集合中存储元素
ts.add("a") ;
ts.add("a") ;
ts.add("b") ;
ts.add("e") ;
ts.add("f") ;
ts.add("d") ;
ts.add("h") ;
ts.add("e") ;
ts.add("c") ;
//遍历
for(String i : ts) {
System.out.print(i +" ");
}
}
}
显示:
a b c d e f h
使用TreeSet集合存储自定义对象时有两种排序方式:
自然排序:自定义的类实现Comparable接口并重写compareTo方法,然后创建TreeSet对象,通过无参构造形式创建对象
比较器排序 :通过有参构造形式创建TreeSet对象public TreeSet(Comparator<E> comparator)【 1)自定义一个类,该类实现Comparator接口,重写Comparator接口中的compare()方法 2)直接使用接口匿名内部类的方式实现】
自然排序:
//创建一个学生类并实现Comparable接口
public class Student implements Comparable<Student> {
private String name;
private int age;
private int id;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//重写compare To方法
@Override
public int compareTo(Student s) {
int sum=this.name.compareTo(s.getName());
int sum2=sum==0? this.age-s.getAge():sum;
int sum3=sum2==0?this.id-s.getId():sum2;
return sum3;
}
}
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>();
Student s1=new Student("zhangsan",16,45);
Student s2=new Student("lisi",17,45);
Student s3=new Student("wangwu",17,49);
Student s4=new Student("zhangsan",17,34);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
Iterator<Student> i = ts.iterator();
while(i.hasNext()) {
Student s=i.next();
System.out.println(s.getName()+" "+s.getAge()+" "+s.getId());
}
}
}
显示:
lisi 17 45
wangwu 17 49
zhangsan 16 45
zhangsan 17 34
比较器排序:
//创建一个学生类
public class Student {
private String name;
private int age;
private int id;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
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;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {//使用匿名内部类的方式
重写compare方法
@Override
public int compare (Student o1, Student o2) {
int sum=o1.getName().compareTo(o2.getName());
int sum2=sum==0? o1.getAge()-o2.getAge():sum;
int sum3=sum2==0?o1.getId()-o2.getId():sum2;
return sum3;
}
});
Student s1=new Student("zhangsan",16,45);
Student s2=new Student("lisi",17,45);
Student s3=new Student("wangwu",17,49);
Student s4=new Student("zhangsan",17,34);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
Iterator<Student> i = ts.iterator();
while(i.hasNext()) {
Student s=i.next();
System.out.println(s.getName()+" "+s.getAge()+" "+s.getId());
}
}
}
显示:
lisi 17 45
wangwu 17 49
zhangsan 16 45
zhangsan 17 34
十、Map集合
Map是一个存储关键字/值对的集合。给定一个关键字就能得到他的值,关键字和值都是对象。Map<K,V>接口的子实现类:HashMap和TreeMap
Map接口的功能:
添加功能:
V put(K key,V value) :将指定的值和键关联起来
如果当前的这个键是一次存储,则返回值null
如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉!
删除功能
void clear():删除所有映射关系
V remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除
判断功能:
boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true
boolean containsValue(Object value):映射关系中是否包含指定的值
boolean isEmpty():判断映射关系是否为空
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<String,String> map=new HashMap<String,String>();
//添加功能,如果当前的这个键是一次存储,则返回值null
System.out.println(map.put("abc", "xyz"));
// 如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉
System.out.println(map.put("abc","qwe"));
map.put("abc2", "hjk");
map.put("abc3", "yui");
System.out.println("map:"+map);
//判断该映射是否含有键"abc3";
System.out.println("是否含有键\"abc3\":"+map.containsKey("abc3"));
//判断该映射是否含有值"xyz";
System.out.println("是否含有值\"xyz\":"+map.containsKey("xyz"));
//删除键"abc3"所对应的映射,则返回值
System.out.println(map.remove("abc3"));
//删除全部映射
map.clear();
//判断映射集合是否为空
System.out.println("是否为空映射:"+map.isEmpty());
}
}
显示:
null
xyz
map:{abc=qwe, abc3=yui, abc2=hjk}
是否含有键"abc3":true
是否含有值"xyz":false
yui
是否为空映射:true
获取功能
Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
Set<K> keySet():获取映射关系中所有的键的集合
int size()返回此映射中的键-值映射关系数
Map集合的两种遍历方式
(1)
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args) {
Map<String,Integer> mp=new HashMap<String,Integer>();
//添加映射
mp.put("刘备", 27);
mp.put("董卓", 47);
mp.put("曹操", 29);
mp.put("孙权", 25);
//遍历
//获取所有的键的集合
Set<String> set=mp.keySet();
for(String key:set) {
//通过键获取值
Integer value=mp.get(key);
System.out.println(key+" "+value);
}
}
}
显示:
董卓 47
孙权 25
刘备 27
曹操 29
(2)
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args) {
Map<String,Integer> mp=new HashMap<String,Integer>();
//添加映射
mp.put("刘备", 27);
mp.put("董卓", 47);
mp.put("曹操", 29);
mp.put("孙权", 25);
//遍历
//获取所有的键值对对象
Set<Map.Entry<String, Integer>> entrySet = mp.entrySet() ;
//增强for
for(Map.Entry<String,Integer> entry :entrySet) {
//获取到每一个键值对对象
//通过键值对对象找键和值
String key = entry.getKey() ;
Integer value = entry.getValue() ;
System.out.println(key+"="+value);
}
}
}
显示:
董卓=47
孙权=25
刘备=27
曹操=29
十一、HashMap集合
HashMap集合本身基于哈希表它可以保证键的唯一性(Map都是针对键有效),但是无法保证存取输出顺序的一致性;
//创建一个人类
public class People {
private String name;
private int age;
public People() {
super();
// TODO Auto-generated constructor stub
}
public People(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;
}
}
------------------------------------------------------------------
HashMap<String,String>
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String,People> hm=new HashMap<String,People>();
//创建人类对象
People p1=new People("赵云",24);
People p2=new People("吕布",29);
People p3=new People("马超",24);
People p4=new People("郭嘉",27);
//存取对象
hm.put("004", p4);
hm.put("001", p1);
hm.put("002", p2);
hm.put("003", p1);
hm.put("003", p3);
//遍历
//获取所有键的集合
Set<String> set=hm.keySet();
for(String key:set) {
//通过键获取值
People value =hm.get(key);
System.out.println(key+" "+value.getName()+" "+value.getAge());
}
}
}
显示:
001 赵云 24
002 吕布 29
003 马超 24
004 郭嘉 27
十二、LinkedHashMap集合
LinkedHashMap<K,V> :是Map接口基于哈希表和链接列表实现的哈希表保证键的唯一性
链接列表保证元素有序性(存储和取出一致)
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<People,String> lhm=new LinkedHashMap<People,String>();
//创建人类对象
People p1=new People("赵云",24);
People p2=new People("吕布",29);
People p3=new People("马超",24);
People p4=new People("郭嘉",27);
//存储对象
lhm.put(p1, "1201");
lhm.put(p2, "1202");
lhm.put(p3, "1203");
lhm.put(p4, "1204");
//遍历
//获取键值对对象的集合
Set<Map.Entry<People,String>> set=lhm.entrySet();
for(Map.Entry<People,String> map:set) {
//获取键
People key=map.getKey();
//获取值
String value=map.getValue();
System.out.println(key.getName()+" "+key.getAge()+" "+value);
}
}
}
显示:
赵云 24 1201
吕布 29 1202
马超 24 1203
郭嘉 27 1204
十三、TreeMap集合
TreeMap类使用树实现Map接口。TreeMap提供了按顺序存储关键字/值对的有效存储方式。import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo1 {
public static void main(String[] args) {
TreeMap<String,Integer> tm=new TreeMap<String,Integer>();
//添加对象
tm.put("ads", 21);
tm.put("eds", 22);
tm.put("bds", 23);
tm.put("cds", 24);
//遍历
//获取所有的键集合
Set<String> set=tm.keySet();
for(String key:set) {
//通过键获取值
Integer value=tm.get(key);
System.out.println(key+" "+value);
}
}
}
显示:
ads 21
bds 23
cds 24
eds 22
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapDemo2 {
public static void main(String[] args) {
TreeMap<Integer,String> tm=new TreeMap<Integer,String>();
//添加元素
tm.put(34, "azz");
tm.put(32, "bzz");
tm.put(35, "czz");
tm.put(33, "dzz");
//遍历
//获取所有键值对的集合
Set<Map.Entry<Integer, String>> set=tm.entrySet();
Iterator<Map.Entry<Integer, String>> it=set.iterator();
while(it.hasNext()) {
//获取键
Integer key=it.next().getKey();
//获取值
String value=tm.get(key);
System.out.println(key+" "+value);
}
}
}
显示:
32 bzz
33 dzz
34 azz
35 czz
TreeMap集合按照键的升序进行排序;
TreeMap集合存储自定义对象
当自定义对象作为键存储时有两种排序方式:
自然排序:自定义的类实现Compareable接口并重写compareTo方法,然后创建TreeSet对象,通过无参构造形式创建对象
比较器排序 :通过有参构造形式创建TreeMap对象public TreeMap(Comparator<E> comparator)【 1)自定义一个类,该类实现Comparator接口,重写Comparator接口中的compare()方法
2)直接使用接口匿名内部类的方式实现】
方式一:
public class Student implements Comparable<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 int compareTo(Student s) {
//以年龄从小到大进行排序
int sum=this.age-s.getAge();
int sum2= sum==0?this.name.compareTo(s.getName()):sum;
return sum2;
}
}
import java.util.Set;
import java.util.TreeMap;
//当自定义对象作为键存储时方式一
public class TreeMapDemo3 {
public static void main(String[] args) {
TreeMap<Student,String> tmp=new TreeMap<Student,String>();
//创建学生对象
Student s1=new Student("宋江",29);
Student s2=new Student("武松",23);
Student s3=new Student("杨志",24);
Student s4=new Student("鲁智深",28);
//添加对象
tmp.put(s1, "0198");
tmp.put(s2, "0196");
tmp.put(s3, "0197");
tmp.put(s4, "0192");
//遍历
//获取所有键的集合
Set<Student> set=tmp.keySet();
for(Student key:set) {
//获取值
String value=tmp.get(key);
System.out.println(key.getName()+" "+key.getAge()+" "+value);
}
}
}
显示:
武松 23 0196
杨志 24 0197
鲁智深 28 0192
宋江 29 0198
方式二:
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;
}
}
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest {
public static void main(String[] args) {
TreeMap<Student,String> ss=new TreeMap<Student,String>(new Comparator<Student>() {
//按照年龄从小到大
@Override
public int compare(Student s1, Student s2) {
int sum=s1.getAge()-s2.getAge();
int sum2=sum==0?s1.getName().compareTo(s2.getName()):sum;
return sum2;
}
});
//创建学生对象
Student s1=new Student("宋江",29);
Student s2=new Student("武松",23);
Student s3=new Student("杨志",24);
Student s4=new Student("鲁智深",28);
//添加对象
ss.put(s1, "0198");
ss.put(s2, "0196");
ss.put(s3, "0197");
ss.put(s4, "0192");
//遍历
//获取所有键的集合
Set<Student> set=ss.keySet();
for(Student key:set) {
//获取值
String value=ss.get(key);
System.out.println(key.getName()+" "+key.getAge()+" "+value);
}
}
}
显示;
武松 23 0196
杨志 24 0197
鲁智深 28 0192
宋江 29 0198
十四、Collections类
Collection和Collections的区别:Collection:顶层次单列集合的根接口,它是一个集合,是一个接口
Collections:是针对集合操作的工具类,有一些功能:随机置换,集合里面的二分查找,将集合的元素进行反转
public static <T> int binarySearch(List<T> list, T key):集合的二分查找(集合必须是有序的)
static T max(Collection coll):获取集合中的最大值
public static void reverse(List<?> list):将集合中的元素顺序反转
public static void shuffle(List<?> list):将集合中的元素打乱
public static void sort(List<T> list):将集合中的元素排序
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<String> as=new ArrayList<String>() ;
//添加元素
as.add("abc");
as.add("bbc");
as.add("cbc");
as.add("dbc");
as.add("ebc");
as.add("fbc");
System.out.println(as);
//获取最大值
System.out.println(Collections.max(as));
//将集合元素反转
Collections.reverse(as);
System.out.println(as);
//打乱集合中的元素
Collections.shuffle(as);
System.out.println(as);
//对集合进行排序
Collections.sort(as);
System.out.println(as);
//二分查找
System.out.println(Collections.binarySearch(as,"fbc"));
}
}
显示:
[abc, bbc, cbc, dbc, ebc, fbc]
fbc
[fbc, ebc, dbc, cbc, bbc, abc]
[ebc, dbc, abc, fbc, bbc, cbc]
[abc, bbc, cbc, dbc, ebc, fbc]
5
练习
模拟斗地主游戏,进行洗牌,发牌且发到每个人手里安顺序排列
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
//思路:将所有的牌都存入HashMap集合里,通过控制键的顺序从而控制牌的顺序
//将所有键存入在ArrayList集合中,使用shuffle()方法进行洗牌,遍历ArrayList集合进行发牌
public class Poker {
public static void main(String[] args) {
//创建一个Map集合来存储牌
HashMap<Integer,String> pa=new HashMap<Integer,String>();
//创建一个List集合用来存储所有的键
ArrayList<Integer> as=new ArrayList<Integer>();
String[] color= {"♥","♠","♣","♦"};
String[] number= {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
int index=0;
for(String c:color) {
for(String n:number) {
//对字符进行拼接,并存入集合
String s=c.concat(n);
pa.put(index, s);
as.add(index);
index++;
}
}
//加入大王小王
pa.put(index,"大王");
as.add(index);
index++;
pa.put(index,"小王");
as.add(index);
//洗牌
Collections.shuffle(as);
//发牌,为了保证发到的牌有序,使用TreeSet集合接收
//三个玩家
TreeSet<Integer> player1=new TreeSet<Integer>();
TreeSet<Integer> player2=new TreeSet<Integer>();
TreeSet<Integer> player3=new TreeSet<Integer>();
//底牌
TreeSet<Integer> di=new TreeSet<Integer>();
for(int x=as.size()-1;x>=0;x--) {
if(x<3) {
di.add(as.get(x));
}
else if(x%3==0) {
player1.add(as.get(x));
}
else if(x%3==1) {
player2.add(as.get(x));
}
else if(x%3==2) {
player3.add(as.get(x));
}
}
// 看牌
looking("玩家1",player1,pa);
looking("玩家2",player2,pa);
looking("玩家3",player3,pa);
looking(" 底",di,pa);
}
public static void looking(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm) {
System.out.print(name+"的牌是:");
//获取键
for(Integer key:ts) {
//获取值
String value=hm.get(key);
System.out.print(value+"\t");
}
System.out.println();
}
}
玩家1的牌是:♥6 ♥Q ♠6 ♠7 ♠10 ♠Q ♣A ♣2 ♣4 ♣Q ♦A ♦4 ♦6 ♦J ♦K 大王 小王
玩家2的牌是:♥A ♥3 ♥4 ♥10 ♥K ♠2 ♠4 ♠5 ♠8 ♣3 ♣5 ♣9 ♣J ♦2 ♦5 ♦7 ♦9
玩家3的牌是:♥2 ♥5 ♥7 ♥8 ♥9 ♠A ♠3 ♠9 ♠J ♠K ♣6 ♣7 ♣8 ♣10 ♦3 ♦10 ♦Q
底的牌是:♥J ♣K ♦8