集合框架
基本的集合框架如下:
而我们常见的几种集合框架如下:
、
一、基本操作
基本操作为增、删、改;
1.获取个数,集合长度.
sop("size:"+a1.size());
2.删除元素
a1.remove("test02");//删除集合内的某个对象.
sop(a1);
a1.clear();//清空集合.
3.判断
sop("test03是否存在:"+a1.contains("test03"));
sop("是否为空?"+a1.isEmpty());
4.取交集
a1.retainAll(a2);//取交集,只保留a1和a2中相同的元素
二、迭代器
迭代器:
/*
1. add方法的参数类型是object。以便于接受任何实体对象。
2. 集合中存储的都是对象的地址。
3. 迭代是取出集合中元素的一种方式。 对于集合的元素取出这个动作:当不足以用一个函数来描述,需要用多个功能来体现,所以就将取出这个动作封装成一个对象来描述。就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。
那么取出方式就被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都具有共性内容: 判断和取出。那么就可以将这些共性抽取。 那么这些内部类都符合一个规则(或者说都抽取出来一个规则)。该规则就是Iterator。
通过一个对外提供的方法:iterator();,来获取集合的取出对象。
***迭代器的next方法返回值类型是Object,所以要记得类型转换。***
*/
public static void method_get()//从容器中取出元素
{
ArrayList<String> a1 = new ArrayList<>();
a1.add("test01");
a1.add("test02");
a1.add("test03");
a1.add("test04");
a1.add("test05");
sop(a1);
for(Iterator<String> iter = a1.iterator();iter.hasNext();)//第一种打印方式,用for循环可以释放内存。000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000<span id="transmark"></span>
{
System.out.println(iter.next());
}
//Iterator<String> it = a1.iterator();//获取迭代器,用于取出集合中内容
//while(it.hasNext())//有元素可以迭代,就返回true
//{
//sop(it.next());//输入迭代器内容,打印下一个元素
//}
}
三、List
Conllection:
List:元素是有序的,且可以重复,因为该集合存在索引。它独有的可以修改某个元素。(可以在指定位置插入元素,可以获取位置,可以根据位置获取元素等)
--ArrayList:底层的数据结构是使用的是数组结构。特点:查询比较快,但是增删比较慢
--LinkedList:底层的数据结构是链表结构。特点:增删比较快,查询稍慢
--Vector:底层是数组数据结构。比ArrayList早,功能一样。但是Vector是同步的,ArrayList线程不同步。
Set:元素是无序的,不能重复。
List:
特有方法:凡是可以操作角标的都是该体系特有的方法。
增:
add(index,element);
addAll(index,Collection);
删:
remove(index);
改:
set(index,element);
查:
get(index);
Iterator;//迭代器;
indexOf(element);//获取某个元素的位置
subList(from,to);//获取from至to的元素,包含from,不包含to:[from,to);
listIterator();//列表迭代器,List所特有的
在迭代过程中,准备添加和删除元素。
List集合特有的迭代器。listIterator()是Iterator()的子接口。
在迭代中,Iterator()的方法是有限的,只有判断,取出, 删除,要想有其他操作就必须使用listIterator()。
示例代码:
for(ListIterator<String> it = a1.listIterator();it.hasNext();)
{
Object obj = it.next();
if(obj.equals("test03"))
{
it.add("test08");//增加一个元素
}
sop("listIterator_obj="+obj);
}
for(ListIterator<String> it = a1.listIterator();it.hasNext();)
{
Object obj = it.next();
sop("listIterator_Obj="+obj);
}
LinkedList特有方法:
示例代码:
class Stack//堆栈
{
private LinkedList<Object> link;
Stack()
{
link = new LinkedList<>();
}
public void stack_add(Object obj)//堆栈增加元素
{
link.addFirst(obj);
}
public Object stack_Get()//获取堆栈元素
{
return link.removeFirst();
}
public boolean stack_IsNull()//判断堆栈是否为空
{
return link.isEmpty();
}
}
class Queue//队列
{
private LinkedList<Object> link;
Queue()
{
link = new LinkedList<>();
}
public void queue_add(Object obj)//队列增加元素
{
link.addFirst(obj);
}
public Object queue_Get()//获取队列元素
{
return link.removeLast();
}
public boolean queue_IsNull()//判断队列是否为空
{
return link.isEmpty();
}
}
List练习:
package Container;
import java.util.*;
/*
**将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
* 比如:存人对象。同名同年龄,视为同一人,为重复元素。//注意判断重复时候要重写equals()方法,因为计算机不知道怎么定义自定义元素是否相等。
* 思路:
* 1.对人描述,数据封装如对象。
* 2.定义容器,将人存入。
* 3.取出。
*
*
*
******List集合判断元素是否相同,依据是元素的equals方法。******
*/
class Person//定义人对象
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)//重写equals方法<span id="transmark"></span>
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"----vs----"+p.name);
return this.name.equals(p.name)&&this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class ArrayListDemo1 {
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static ArrayList<Person> singleElement(ArrayList<Person> al)//去重复元素
{
//定义一个临时容器
ArrayList<Person> newAl = new ArrayList<>();
for(Iterator<Person> it = al.iterator();it.hasNext();)
{
Person p = it.next();
if(!newAl.contains(p))//必须要重写equals方法,contains的基础是equals方法。
newAl.add(p);
}
return newAl;
}
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("asla01",12));
al.add(new Person("asla01",12));
al.add(new Person("asla02",22));
al.add(new Person("asla03",15));
al.add(new Person("asla04",31));
al.add(new Person("asla05",21));
al.add(new Person("asla05",21));
al = singleElement(al);
for(Iterator<Person> it = al.iterator();it.hasNext();)
{
Person p = it.next();//如果上面没有定义Person类型,这里就必须强行转换。
sop(p.getName()+"::"+p.getAge());
}
}
}
总结:频繁的增删操作采用LinkedList,频繁的查询使用ArrayList。一般的情况下都使用ArrayList,因为它的底层数据结构是数组结构,查询快。而LinkedList的底层数据结构是链表,便于增删,但是查询较慢。
四、Hashset
set:元素是无序的,且不能重复。
|--Set:元素无序,且不能重复。
|--HashSet:底层结构是哈希表。
HashSet如何保证元素的唯一性呢?
通过元素的hashCode和equals方法完成。当hashCode值相同时候,才会判断equals。
|--TreeSet:
Set集合的功能和Collection是一致的。
具体上代码:
package Container;
import java.util.HashSet;
import java.util.Iterator;
/*
|--Set:元素无序,且不能重复。
|--HashSet:底层结构是哈希表。
HashSet如何保证元素的唯一性呢?
通过元素的hashCode和equals方法完成。当hashCode值相同时候,才会判断equals。
注意:判断元素是否存在,删除等操作,都依赖hashCode和equals方法。<span id="transmark"></span>
|--TreeSet:
Set集合的功能和Collection是一致的。
*/
class Person1//定义人对象
{
private String name;
private int age;
Person1(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)//重写equals方法。
{
if(!(obj instanceof Person1))
return false;
Person1 p = (Person1)obj;
System.out.println(this.name+"----vs----"+p.name);
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode() //重写hashCode方法
{
return this.name.hashCode()+this.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class HashSetDemo {
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args) {
HashSet<Person1> hs = new HashSet<>();
hs.add(new Person1("lisa01",21));
hs.add(new Person1("lisa02",21));
hs.add(new Person1("lisa02",21));
hs.add(new Person1("lisa03",21));
hs.add(new Person1("lisa04",21));
for(Iterator<Person1>it = hs.iterator();it.hasNext();)
{
Person1 p = it.next();
sop(p.getName()+"--------"+p.getAge());
}
}
}
五、TreeSet
|--TreeSet:可以对其中元素进行自然排序。排序的时候,主要条件相同时候,要比较次要条件。
底层数据结构是二叉树。
他的排序方式是compareTo方法。TreeSet的删除,查找都基于此方法。
TreeSet排序的第一种方式:让元素具有比较性。需要实现Comparable端口,覆盖conpareTo方法。
这种方式又叫自然顺序或者默认顺序。
TreeSet排序的另一种方式是:当元素自身不具备比较性时候,或者具备的比较性不是所需要的。这时候需要让集合自身具备比较性。
第一种排序方式:
import java.util.Iterator;第二种比较方式:
import java.util.TreeSet;
class People implements Comparable<Object>//定义人对象,Comparable强制让学生具有可比较性
{
private String name;
private int age;
People(String name, int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)//重写compareTo方法
{
if(!(obj instanceof People))
throw new RuntimeException("不是一个人");
People p = (People)obj;
if(this.age > p.age)//判断大于
return 1;
if(this.age==p.age)//当年龄相同时,比较姓名。
{
return this.name.compareTo(p.name);
}
return -1;//判断小于
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class TreeSetDemo
{
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args)
{
TreeSet<People> ts = new TreeSet<>();
ts.add(new People("test1",10));
ts.add(new People("test2",20));
ts.add(new People("test3",5));
ts.add(new People("test5",5));
ts.add(new People("test4",7));
for(Iterator<People> it = ts.iterator();it.hasNext();)
{
People p = it.next();
sop(p.getName()+"----"+p.getAge());
}
}
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/*
当元素自身不具备比较性,或者具备的比较性不是所需的,这时候需要让容器自身具备比较性。
定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
两种比较器都存在时候以比较器为主
定义一个比较器,实现Comparator端口,覆盖compareTo方法。
*/
/**************第二种比较方式******************/
class MyCompare implements Comparator<Object>//比较器
{
public int compare(Object o1,Object o2)
{
People1 p1 = (People1)o1;
People1 p2 = (People1)o2;
int num;
num = p1.getName().compareTo(p2.getName());//比较姓名
if(num == 0)//如果姓名相同,比较年龄
{
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));//将整数封装,然后调用方法比较
/*if(p1.getAge()>p2.getAge()) return 1;
else if(p1.getAge()==p2.getAge()) return 0;
return -1;*/
}
else
return num;
}
}
class People1 implements Comparable<Object>//定义人对象,Comparable强制让学生具有可比较性
{
private String name;
private int age;
People1(String name, int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)//重写compareTo方法
{
if(!(obj instanceof People1))
throw new RuntimeException("不是一个人");
People1 p = (People1)obj;
if(this.age > p.age)//判断大于
return 1;
if(this.age==p.age)//当年龄相同时,比较姓名。
{
return this.name.compareTo(p.name);
}
return -1;//判断小于
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class TreeSetDemo2
{
public static void sop(Object obj)//打印
{
System.out.println(obj);
}
public static void main(String[] args)
{
TreeSet<People1> ts = new TreeSet<>(new MyCompare());//传入比较器
ts.add(new People1("Zhangsan",10));
ts.add(new People1("Lisi",20));
ts.add(new People1("Wangwu",5));
ts.add(new People1("Zhangsan",5));
ts.add(new People1("Lilei",7));
for(Iterator<People1> it = ts.iterator();it.hasNext();)
{
People1 p = it.next();
sop(p.getName()+"----"+p.getAge());
}
}
}