Java中的集合类
一:介绍集中常用的集合:
1】Collection
2】Set
3】List
4】Queue
二:下面给出用例图:
注:CollectionUML用例图
三:Java中,集合与数组的比较:
1】在Java中,集合的产生可以极大的方便了对于一组相同数据类型的集合的操作;
2】集合的长度,可以很方便的动态的改变,而数组很难做到动态改变长度;
3】Java中的数组,只可以存储基本的数据类型,而不可以存储任意自定义对象,比如数据的封装类;
四:Set、Map、List集合的特性比较:
(1)Set集合:
①:Set集合就像一个罐子,它是无序的集合,其中的数据元素是散乱排放;
②:Set集合,不会按照元素被放入的先后顺序,进行存放;
③:在使用Set集合时,规定上不能有两个重复值的放入;
④:在Set如何判断两个对象是否相等:
1°:首先判断两个值是否相等;
2°:判断两个数据在set集合中的hashCode值是否相同;
只有满足上述的两种情况,才算是,两个Set中的对象相等;
⑤:Set集合中可以插入一个Null数据;
(2)Map集合:
①:Map集合,最大的特点就是按照Key--Value的形式存入集合中;
②:其和Set集合一样,在排布结构中也是杂乱无章的;
(3)List集合:
①:List集合原理有点像数组,其可以记住元素放入的先后顺序;
②:List集合的长度是灵活的,这点又优于数组;
五:下面将介绍几个常用的集合类:
(1)Connection:
1.1 常用的方法:
- add(Object) 向集合中加入一个对象 返回Boolean类型
- addAll(Collection) 向集合中加入一个完整的集合 返回Boolean类型
- contains(Object Obj) 查看集合中是否有Obj对象 返回Boolean类型
- iterator( ) 用于遍历 返回一个Iterator对象
1.2 下面贴出Collection常用的方法:
public static void main(String[] args){
Collection<String> c=new ArrayList<String>();
c.add(new String("软件1522班级"));
c.add(new String("我是孙悟空"));
c.add(new String("Java教程"));
//打印出: [软件1522班级, 我是孙悟空, Java教程]
System.out.println(c);
boolean b=c.contains(new String("Java教程"));
//打印出: true
System.out.println(b);
Collection<String> c2=new ArrayList<String>();
c2.add(new String("我是孙悟空"));
c.removeAll(c2);
//打印出: [软件1522班级, Java教程]
System.out.println(c);
}
(2)Set:
2.1 常用方法: 与Collection相类似
2.2 上面说,Set集合中规定不能存在重复值,这是为了防止Set中出现混乱,下面用一组代码进行说明:
package njcc.java.collection;
import java.util.HashSet;
import java.util.Iterator;
public class SetCollection {
//首先写入一个内部类
static class SetColl{
private int count;
public SetColl(){}
public SetColl(int count){
this.count=count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
//重写ToString方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "{"+count+"}";
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.count;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(this==obj) return true;
SetColl s=(SetColl) obj;
if(s.count==this.count) return true;
return false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<SetColl> hash=new HashSet<SetColl>();
//不按照大小的存放
hash.add(new SetColl(5));
hash.add(new SetColl(-5));
hash.add(new SetColl(9));
hash.add(new SetColl(10));
//打印出: [{-5}, {5}, {9}, {10}]
System.out.println(hash); //由此可以说明set集合中是不记对象存入的顺序
Iterator it=hash.iterator();
//因为it.next()返回的是Object对象,因此需要强制转换
SetColl set=(SetColl)it.next();
//将第一个数据改成5
set.count=9;
//打印出: [{9}, {5}, {9}, {10}]
System.out.println(hash);
boolean b1=hash.contains(new SetColl(9));
//输出true 至于输出的是哪一个9,那么一定是第二个9了
/*
* 起初第一次便利为[{-5}, {5}, {9}, {10}]
* 其HashCode的假设为:01 02 03 04
* 当第一个数据-5变成9的时候,变为:[{9}, {5}, {9}, {10}]
* 但是其HashCode依然为: 01 02 03 04
* 而,在比较Set两个对象是都一样的时候,要比较其数值一样,HashCode也必须一样,因为输出的为第二个9
*/
System.out.println(b1);
}
}
2.3 在Set中还有一个实现类:TreeSet,而上面介绍的是HashSet:
①:TreeSet和HashSet的比较:
两者都有相似点:即,两种集中的(其实就是Set集合),一旦数据定下来之后,尽量不要改变某一个数据,这样会使得Set集合变得很乱;
两者的不同之处:在TreeSet中,必须实现Comparable接口进行排序;
2.4 下面代码说明TreeSet:
package njcc.java.collection;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetCollection {
static class Tree implements Comparable{
private int count;
private String name;
public Tree(){};
public Tree(int count,String name){
this.count=count;
this.name=name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//重写toString方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "{"+count+","+name+"}";
}
public int compareTo(Object o) {
// TODO Auto-generated method stub
Tree tree=(Tree) o;
return count-tree.count;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Tree> set=new TreeSet<Tree>();
set.add(new Tree(5,"张三"));
set.add(new Tree(1,"李四"));
set.add(new Tree(3,"王五"));
set.add(new Tree(2,"赵六"));
set.add(new Tree(4,"小五"));
//输出: [{1,李四}, {2,赵六}, {3,王五}, {4,小五}, {5,张三}]
System.out.println(set);
Iterator<Tree> in=set.iterator();
in.next().count=10;
//输出: [{10,李四}, {2,赵六}, {3,王五}, {4,小五}, {5,张三}]
System.out.println(set);
/*
* 虽然这里,TreeSet实现了,Compare的排序,但是,后来将第一个元素改变了值,
* 而TreeSet不会因为值的变化,而进行重新排布;
* 就算是TreeSet中,有一个元素被删除了,TreeSet也只是会改变其数据的索引,但不会
* 重新排布数据元素
*/
System.out.println(set);
}
}
(3)List:List中分为ArrayList和Vector
3.1 两者的比较:
①都是List的实现类;
②都是对于Java中数组的扩充;
③比较于数组,其可以自由的扩展自己的空间;
④在线程安全这一块中,Vector本身就是同步的,是线程安全的;
(4)Collections:
4.1Collections与Collection的区别:
①Collection其本质是接口,见本文章中的图例①就不难看出;
②Collections则是在java.util包中的类,它包含有各种有关集合操作的静态方法;
4.2下面说明Collections中常用的sort排序方法,其中sort的第一个参数必须为List类型:
package njcc.java.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
public class Compare {
static class Tree implements Comparable<Tree>{
private int count;
private String name;
public Tree(){};
public Tree(int count,String name){
this.count=count;
this.name=name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//重写toString方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "{"+count+","+name+"}";
}
public int compareTo(Tree o) {
// TODO Auto-generated method stub
return count-o.count;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Tree> list=new ArrayList<Tree>();
list.add(new Tree(5,"张三"));
list.add(new Tree(1,"李四"));
list.add(new Tree(3,"王五"));
list.add(new Tree(2,"赵六"));
list.add(new Tree(4,"小五"));
Collections.sort(list);
for(Tree obj:list){
System.out.println(obj);
}
}
}
这一种方式中,可以看出,在Java的数据封装层中,实现了Comparable的接口,所以,可以直接选择sort(arg0)的方法;
现在对比下一种写法:
package njcc.java.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
public class Compare2 {
static class Tree{
private int count;
private String name;
public Tree(){};
public Tree(int count,String name){
this.count=count;
this.name=name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//重写toString方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "{"+count+","+name+"}";
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Tree> list=new ArrayList<Tree>();
list.add(new Tree(5,"张三"));
list.add(new Tree(1,"李四"));
list.add(new Tree(3,"王五"));
list.add(new Tree(2,"赵六"));
list.add(new Tree(4,"小五"));
//在数据封装层中未实现comparable接口,而是选择sort中,带有两个参数的方法,第一个参数为,需要进行排序的对象,
//第二个参数为,自定义的一个比较器
Collections.sort(list,new Comparator<Tree>(){
@Override
public int compare(Tree arg0, Tree arg1) {
// TODO Auto-generated method stub
return arg0.count-arg1.count;
}
});
for(Tree obj:list){
System.out.println(obj);
}
}
}
在上面这种方式中,可以看出,在Java的数据封装层中没有时间Comparable的接口,而是直接选择sort(arg0,arg1)的方法,
其中第一个参数为需要比较的List集合,其中具有很多Java封装层的对象,第二个参数为自定义的一起比较器,这里采用的是升序的方式,进行排序。
(五)总结:
在学习了上述集合之后,会发现,List对于查找非常的方便,因为其和数组相似具有链式结构;
而Set集合,是按照树的结构来进行排布,所以,插入和删除节点非常的方便,但是读取数据,有一定的难度,尤其是对于,改变某一个数值之后的查找,那更加的
糟糕。
所以在今后的集合使用中,要具体问题具体分析,之后选择最佳的集合来作为存储容器。