概述
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
集合框架:
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同。
这个存储方式称之为:数据结构。
1、add方法的参数类型是Object。以便接收任意对象。
2、集合中存储的都是对象的引用地址。
共性方法:
//创建一个集合容器。使用Collection接口的子类。ArrayList
ArrayList al = new ArrayList();
1.添加元素。
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//打印集合。
System.out.println(al); [java01,java02,java03,java04]
2、获取个数,集合长度。
al.size();
3、删除元素。
al.remove("java02")//移走一个元素
al.clear();//清空集合
4、判断元素。
java03是否存在: al.contains("java03");
集合是否为空? al.isEmpty();
5、取交集。
boolean retainAll(Collection c) 仅保留此collection中哪些包含在指定collection的元素。
public static void method_2()
{
ArrayList<E> al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java01");
al2.add("java02");
al2.add("java05");
al2.add("java06");
al1.retainAll(al2);//取交集,al1中只会保留和al2相同的元素。
}
结果:al1里面的元素有:java01、java02.
去交集。
al1.removeAll(al2);
结果:al1里面的元素有:java03、java04.
6、元素取出。
Iterator iterrator()//返回Iterator接口的子类对线。
返回在此collection的元素上进行迭代的迭代器。
Iterator接口:
boolean hasNext()
如果仍有元素可以迭代,则返回true。
next()
返回迭代的下一个元素。
void remove()
从迭代器指向的collection中移除迭代器返回的最后一个元素。
什么是迭代器呢?
其实就是用于取出集合中元素的方式。
迭代器使用示例:
public static void method_get()
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//通过集合的itarator方法获取了一个Iterator的子类对象。
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。
while(it.hasNext())
System.out.println(it.next());
}
每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共享内容:判断和取出。
那么可以将这些共性抽取。
这些内部类都符合一个规则。该规则是Iterator。
如何获取集合的取出对象呢?
通过一个对外方法。iterator();
集合元素取出第二种方式:
for(Iterator it = al.iterator();it.hasNext(); )
{
System.out.println(it.next());
}
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。默认长度为10.当数据超过10,延长50%。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
|--Vecor:底层是数组数据结构。JDK1.0时出现。是同步方法。增删,查询都慢。被ArrayList替代了。默认长度为10.当数据超过10时,延长100%。
|--Set:元素是无序的,不可以重复。
List:
特有方法: 凡是可以操作角标的方法都是该体系特有方法。
增:指定位置插入元素
add(index,element);
addAll(index,Collection);
删:指定位置删除元素
remove(index);
改:指定位置改变元素
set(Index,element);
查:查找指定位置的元素。
get(index):
subList(from,to);
listIterator();
List集合特有的迭代器。ListIterator是Iterator的子接口。
ListIterator listIterator()
返回列表元素的列表迭代器。
在用迭代器获取元素时,不能更改该集合中的元素。
当方法检测到对象的并发修改,但不允许这种修改时,抛出异常。
ConcurrentModificationException。
Iterator方法有限。
只能对元素进行判断,取出,删除等操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
ListIterator li = al.listIterator();
while(li.hasNext())
{
Object obj = li.next();
if(obj.equals("java02"))
li.add("java009");//li.set("java006");
}
//逆向获取元素:
while(li.hasPrevious())
System.out.println(li.previous());
Vector特殊方法演示:
方法名称后带Element的都是Vector的方法。
枚举就是Vector特有的取出方法。与Iterator相似。
其实枚举和迭代是一样的。
因为枚举的名称以及方法的名称都过长。
所以被迭代器取代了。
Enumeration en = v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
Linklist方法介绍:
特有方法:
addDirst();
addLast();
getFist();
getLast();
获取元素,但不删除元素。
removeFirst();
removeLast();
获取元素,但删除元素。
以上方法,但列表为空时,抛出异常。NoSuchElementException。
不使用iteraor获取每一个元素。
while(!link.isEmpty())
{
link.removeFirst();
//link.removeLast();
}
JDK1.6出现的方法:
offerFirst()
offerLast()
增加元素。
peekFirst()
peekLast()
获取但不移除列表的元素,为空则返回null。
pollFirst()
pollLast()
获取并移除列表的元素;如果此列表为空,则返回null。
练习:
使用LinkedList模拟一个堆栈或者队列数据结构。
import java.util.LinkedList;
public class StackList
{
public static void main(String[] args)
{
Stack s = new Stack();
s.add("java01");
s.add("java02");
s.add("java03");
s.add("java04");
System.out.println(s);
System.out.println(s.get());
System.out.println(s.get());
}
}
class Stack
{
private LinkedList link ;
Stack()
{
link = new LinkedList();
}
public String toString()
{
return link.toString();
}
public void add(Object obj)
{
link.addFirst(obj);
}
public Object get()
{
if(isEmpty())
{
throw new RuntimeException();
}
else
return link.removeFirst();
}
public boolean isEmpty()
{
return link.isEmpty();
}
}
练习:
去除ArrayList集合中的重复元素。
import java.util.ArrayList;
import java.util.Iterator;
/*
* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
*
* 比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
*/
public class ArrayListTest2
{
public static void main(String[] args)
{
ArrayList<People> AL = new ArrayList<People>();
AL.add(new People("lisi1","18"));
AL.add(new People("lisi2","19"));
AL.add(new People("lisi2","18"));
AL.add(new People("lisi3","17"));
AL.add(new People("lisi4","18"));
AL.add(new People("lisi4","17"));
AL.add(new People("lisi4","17"));
AL.add(new People("lisi4","18"));
ArrayList<People> Array = myCombime( AL);
Iterator<People> it1 = AL.iterator();
while(it1.hasNext())
{
People tp = it1.next();
System.out.println("name="+tp.name+"......."+"age="+tp.age);
}
System.out.println(".....................................");
Iterator<People> it = Array.iterator();
while(it.hasNext())
{
People tp = it.next();
System.out.println("name="+tp.name+"......."+"age="+tp.age);
}
}
public static ArrayList<People> myCombime(ArrayList<People> AL)
{
Iterator<People> it = AL.iterator();
ArrayList<People> Array = new ArrayList<People>();
while(it.hasNext())
{
People p = it.next();
if(!isContains( Array,p))
{
Array.add(p);
}
}
return Array;
}
public static boolean isContains(ArrayList<People> Array , People p)
{
Iterator<People> it = Array.iterator();
while(it.hasNext())
{
People tp =
it.next();
if(tp.name.equals(p.name)
&& tp.age.equals(p.age))
return true;
}
return false;
}
}
class People
{
String name;
String age;
People(String name, String age)
{
this.name = name;
this.age = age;
}
public String getname()
{
return name;
}
public String getage()
{
return age;
}
}
List集合判断元素是否相同,依据的是元素的equals方法。
contains()方法调用的是元素的equals方法。
要判断指定对象是否相等是,必须复写
public boolean equals(Object obj)();//contains调用的方法。覆盖equals方法。
public boolean equals(Person p);//重载这个方法对contains没有用。重载equals方法。
ArrayList :当涉及到频繁增删和查找时使用。
LinkeddList:当涉及到频繁的增删是使用。
Set:元素无序(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。根据hashCode方法判断元素是否相同。存储是按哈希值存储。
HashSet是如何保证元素唯一性?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的hashcode值相关,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
|--TreeSet:
Set集合的功能和Collection是一致的。
import java.util.HashSet;
import java.util.Iterator;
/*
* 往hashSet集合中存入自定义对象。
* 姓名和年龄相同为同一个人,重复元素。
*/
public class HashSetTest
{
public static void main(String[] args)
{
HashSet<Person> hs = new HashSet<Person>();
hs.add(new Person("lisi1",18));
hs.add(new Person("lisi1",19));
hs.add(new Person("lisi2",18));
hs.add(new Person("lisi2",18));
Iterator<Person> it = hs.iterator();
while(it.hasNext())
{
Person p1= it.next();
System.out.println(p1.getName()+"......"+p1.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.setName(name);
this.setAge(age);
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.getName().equals(p.getName()) && this.getAge() == p.getAge();
}
public int hashCode()
{
return 60;
}
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;
}
}
结论:在往HashSet中存数据时,先判断数据的哈希值是否相等,如果相等就调用该数据的equals方法,进一步判断是否相等,相等就不存入。如果哈希值不想等,则直接存入。
所以在往HashSet里面存自定义对象时,先要重写该对象的hashCode()方法,然后再重写equals方法。
hashCode()方法复写:
public int hashCode()
{
return name.hashCode()+age*37;
}
contains方法先判断hashCode是否相等,再判断equals是否相等。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
最后
以上就是欢呼御姐为你收集整理的黑马程序员——集合类(List、Set)的全部内容,希望文章能够帮你解决黑马程序员——集合类(List、Set)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复