1、为什么出现集合类,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最长哟昂的一种方式。
数组与集合类都是容器,有何不同?数组虽然也可以存储对象,但长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。数组只能存储同一种数据类型。
集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
2、容器
collection接口:
List:
ArrayList:底层数据结构使用的是数组结构。特点:查询速度快但增删很慢。
线程不同步。数组默认长度10,当元素数超过10,就new一个新
的数组,长度增长50%。将元素copy过来然后加上新元素
LinkedList:底层使用的是链表数据结构。特点:查询慢增删快
Vector:底层是数组数据结构(Vector是1.0,集合框架是1.2出现的),功能
与ArrayList相同。但是线程同步。低效。数组默认长度10,当元
素数超过10,就new一个新的数组,长度增长100%。将元素
copy过来然后加上新元素
Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
Set集合功能与Collection功能一致
HashSet:底层数据结构是哈希表
TreeSet:
为什么出现这么多容器:因为每一个容器对数据的存储方式不同,这个存储方式称为:数据结构
3、示例:
/*
add方法的参数类型时Object,以便于接收任意类型对象。
集合中存储的都是对象的引用或地址。
Iterator的设计原理:
把集合中取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素。
那么取出方式就被定义成了内部类。
而每一个容器的数据结构不同。
所以取出的动作细节也不一样,但是都有共性内容:判断和取出,那么可以将其共性抽取。
那么这些内部类都复合一个规则,该规则是Iterator接口。
如何获取集合的取出对象,通过一个对外提供的方法iterator();
*/
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
//创建一个集合容器,使用Collection解扣子的子类,ArrayList
ArrayList al = new ArrayList();
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java4");
ArrayList al2 = new ArrayList();
al2.add("java2");
al2.add("java3");
al2.add("java6");
al2.add("java7");
//
Iterator it = al.iterator();//获取迭代器,用于去除集合中的元素。
sop(it.next());//取出集合中下一个元素
while(it.hasNext())//判断下面是否还有元素,返回boolean
{
it.next();
}
for(Iterator it = al.iterator();it.hasNext();)
{
sop(it.next());
}
//取交集
al.retainAll(al2)//al中只会保留和al2中相同的元素,al与al2的交集
//去交集
al.removeAll(al2);//al中保留al2中所没有的元素,即去掉al中二者的交集,但是al2不变
//获取个数
sop("size:"+al.size());
//打印集合中的对象
sop(al);//会依次打印出集合中所有的对象
//删除元素
al.remove("java3");//删除集合中的java3元素
al.clear();//删除集合中所有元素,清空集合。
//判断元素
sop(al.contains("java2");//al中是否包含java2,返回boolean
sop(al.isEmpty());//al是否为空,返回boolean
}
public static void sop(Object obj)
{
System.out.println(obj):
}
}
4、List集合共性方法:
/*
Collection
List:元素师有序的,元素可以重复,因为该集合体系有索引。
Set:元素是无序的,元素不可以重复。
List:
特有方法:凡是可以操作角标的方法都是该体系特有方法
增:
add(index,element);
addAll(index,Collection);
删:
remove(index);
改:
set(index,element)
查:
get(index);
subList(from,to)
listIterator();
List集合特点有的迭代器,ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常:ConcurrentModificationException,所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是优先的,只能对元素进行判断,取出,删除的操作。
如果想要其他的操作如添加、修改等,就需要使用其子接口,ListITerator。
该接口只能通过List集合的listIterator()方法获取。
*/
imort java.util.*;
class ListDemo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
//指定位置添加元素
al.add(1,"java09");
//删除指定位置元素
al.remove(2);
//修改指定位置元素
al.set(2,"java998");
//获取角标处元素
sop(al.get(1));
//获取所有元素
for(Iterator it = al.iterator();it.hasNext();)
{
sop(it.next());
}
//通过indexOf获取对象的位置
sop(al.indexOf("java02");
List sub = al.subList(1,3);//取子列表,包含1不包含3
//演示列表迭代器
//在迭代过程中,准备添加或者删除元素。用Iterator;
Iterator it = al.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals("java02")
it.add("jfava333");//出现并发异常
it.remove();//删除集合中对象的引用
sop(obj)
}
//用ListITerator,因为List有索引,所以能进行增删改查
ListIterator li = al.ListIterator();
while(li.haiNext())//判断集合中下一个元素是否存在:正向遍历
{
Object obj = li.next();
if (obj.equals("java01"))
li.set("java003");
li.add("java3333");
}
while(li.haiPrevious())//判断集合中前一个元素是否存在,逆向遍历
{
Object obj = li.previous();
if (obj.equals("java01")
li.set("java003");
li.add("java3333");
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Vector示例:
/*
枚举就是Vector特有的取出方式
发现枚举和迭代很像
其实枚举和迭代是一样的
因为枚举的名称以及方法的名称都过长
所以被迭代器取代了
枚举就用的少了
*/
class VectorDemo
{
public static void main(String[] args)
{
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en = v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
}
}
5、linkedList
/*
特有方法:
addFirst();
addLast();
getFirst();
getLast();只取不删
removeFirst();取并删
removeLast();
注意当linkedList 为空时,进行上述操作,抛出异常NoSuchElementsException
1.6版本后:出现替代方法
offerFirst();//添加元素
offerLast();
peekFirst();//获取元素,但不删除,如果集合没有元素,返回null,不抛异常
peekLast();
pollFirst();//获取元素,并在链表中删除,如果集合中没有元素,返回null,而不是抛异常
pollLast();
*/
import java.util.*;
class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList link = new LinkedList();
link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java02");
link.addFirst("java03");
sop(link);//结果java03 java02 java01
sop(link);//结果java03 java02 java01
LinkedList link1 = new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addLast("java02");
link.addLast("java03");
sop(link1);//结果java01 java02 java03
sop(link1.getFirst());//java01
sop(link1getLast());//java03
sop(link1.removeFirst());//先获取第一个,然后删除
sop(link1.size());
//删除所有元素
while(!link1.isEmpty())
{
sop(link.removeFirst());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
堆栈:先进后出,如同一个杯子
队列:先进先出,First in First out FIFO如同一个水管
import java.util.*;
class DuiLie
{
private LinkedList link;
DuiLie()
{
link = new LinkedList;
}
public void myAdd(Object obj)
{
link.addFirst(obj);
//ling.addLast(obj);
}
public Object myGet()
{
return link.removeLast();
//return link.removeFirst();
}
public boolean isNull()
{
return link.isEmpty();
}
}
class LinkedListTest
{
public static void main(String[] args)
{
DuiLie dl = new DuiLie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
while(dl.isNull())
{
System.out.println(dl.myGet());
}
}
}
去除ArrayList中的重复元素
class ArrayListDemo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
al.add("java05");
al.add("java06");
System.out.println(singleElement(al));
//在迭代时,循环中的next()调用一次,就要hasNext判断一次。不要hasNext一次而next多次,否则易出NoSuchElementException
Iterater it = al.Iterator();
while(it.hasNext())
{
sop(it.next()+" "+it.next());
//输出:java01....java02 java03......java04 java05......java06
//但是当没有al.add("java06")时,最后一次循环的it.next()取不到值,
//出异常
}
}
public static ArrayList singleElement(ArrayList al)
{
/*
原理:创建新容器,判断该容器中是否含有al中的元素,若没有则添加。(这样,不重复的元素会添加进去,而重复的元素只会添加进一次,等再次添加时新容器中已有该元素,判断为false,因此不添加,这样新容器中就是去除了重复元素的集合,将该新容器返回即可)
*/
ArrayList all = new ArrayList();
Iterator it = al.iterator();
while(it.haiNext())
{
Object obj = it.next();
if(!all.contains(obj))
all.add(obj);
}
}
}
List集合判断元素是否相同,依靠的是equals方法。contains remove
6、频繁增删:linkedList
涉及增删,但不频繁:linkedList 或ArrayList
涉及增删,涉及查询:ArrayList
7、 Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
Set集合功能与Collection功能一致
HashSet:底层数据结构是哈希表
HashSet是如何保证元素的唯一性?是通过元素的两个方法,hashCode()和equals()来完成。如果元素的HashCode值相同,才会判断equals是否为true,如果元素的哈希值不同,不会调用equals。另外:若两个元素的值不同,地址值相同,过程是这样的:先比较地址值,发现相同,然后比较equals,发现值不同,则,在哈希表中,该地址值下回存入两个不同的对象,即一个地址两个对象,在打印时,可打印出这两个对象。
HashSet数据结构式哈希表,线程是非同步的。保证元素唯一性的原理,判断元素的hashCode是否相同,如果相同,还会继续判断元素的equals方法,是否为true
注意:对于判断元素是否存在以及删除等操作,都依赖于元素的hashcode和equals方法
class Demo
{
/*
public int hashCode()
{
return 60;//返回值3c, 十六进制形式
}
*/
}
class HashSetDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
Demo d = new Demo();
Demo d1 = new Demo();
sop(d);//因为重写了hashCode(),所以打印的d和d1的地址值是一样的
sop(d1);//这是因为,d.toString()时,调用hashCode(),返回d的哈希值
//但是我们重写后,返回的是3c,因此d 和d1打印地址值相同
HashSet hs = new HashSet();
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java04");
hs.add("java03");
hs.add("java04");
sop(hs.add("java"));//add方法返回值为boolean的,此时打印true,能存
sop(hs.add("java"));//应为hs中已经存在java,不能继续存入,打印false
Iterator it = hs.iterator();
while(it.hasNext())//打印后只1234,因为HashSet中元素不重复
sop(it.next())
}
}
8、TreeSet:
可以对Set集合中的元素进行排序
底层数据结构式二叉树
调用的是compareTo()方法。
保证元素
唯一性的依据: 调用的是compareTo()方法,返回值为0
排序的第一种方式:让元素自身具备比较性,元素实现compareable接口,覆盖compareTo()方法。这种方式也称为元素的自然顺序,或默认顺序。
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add("fd");
ts.add("cdf");
ts.add("Dd");
ts.add("b");
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
//结果: Dd b cdf fd
//按首字母值排序,升序
}
}
}
/*
向TreeSet中存储自定义对象:重写compareTo方法,按我们自定义的方式返回值,先比较主要元素,若主要元素相同就比较次要元素。
*/
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new Student("zhangsan",19);
ts.add(new Student("lisi",30);
ts.add(new Student("wangwu",19);
ts.add(new Student("zhangsan",13);
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
/*此时按升序排列
if(!(obj instanceof Student))
throw new RunTimeException("不是学生");
Student s = (Student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return (this.name).compareTo(s.name);//String类本身就实现了Compareable接口,有compareTo方法
return -1;*/
//如果这样,那么元素是按存入的顺序排列的,存入元素时,会自动调用compareTo,返回1表示大于,返回0表示等于(此时不存入),返回-1表示小于。在这里全返回1表示后存入的对象比前一个对象大。
return 1;
}
public String getName()
{
return name;
}
public int getAge()
{
retrun age;
}
}
排序的第二种方式:当元素自身不具备比较性,或具备的比较性不是所需要的。这时需要让集合自身具备比较性。在集合一初始化时,就有了比较方式。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
当两种排序都存在时,以比较器为主
定义一个类,实现Comparator接口,覆盖compare方法。
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
此时按升序排列
if(!(obj instanceof Student))
throw new RunTimeException("不是学生");
Student s = (Student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return (this.name).compareTo(s.name);//String类本身就实现了Compareable接口,有compareTo方法
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
retrun age;
}
}
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet
(new MyCompare());
//表示使用指定比较器
ts.add(new Student("zhangsan",19);
ts.add(new Student("lisi",30);
ts.add(new Student("wangwu",19);
ts.add(new Student("zhangsan",13);
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
//结果: Dd b cdf fd
//按首字母值排序,升序
}
}
}
class MyCompare implements Comparator//自定义比较器
{
public int compare(Object c1,Object c2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num==0)//当name相同时,比较age
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge());
}
return num;
}
}
比较器调用过程:
就是让集合具备比较的功能,使用集合构造函数方法
创建TreeSet集合对象,此时:
TreeSet ts = new TreeSet(new MyCompare()); 表示使用自定义比较器
创建类实现接口Comparator,覆盖接口的compare方法
class MyCompare implements Comparator//自定义比较器
{
public int compare(Object c1,Object c2){
自定义比较的方式,最后的返回值return 正数或负数或0;一般就是1 -1 0
}
向TreeSet对象中添加元素,此时元素就自动的,按自定义的比较器在集合内排序存放}
compareTo调用过程理解:
让集合元素具备比较性
创建TreeSet集合对象,此时:
TreeSet ts = new TreeSet(); 表示使用compareTo()方法
创建类实现Comparable接口,覆盖compare方法。并且此类生成的对象,是准备向集合中添加的元素。
在覆盖后的compare方法中对该类的成员如name age等进行比较,返回值1 -1 或0
向集合中添加元素,集合就会自动调用compare方法,按覆盖后的compare方法进行排序存放
本文详细介绍了Java集合框架的基本概念,包括数组与集合的区别、各种集合类的特点及应用场景,如ArrayList、LinkedList、HashSet、TreeSet等,并提供了丰富的示例代码。
&spm=1001.2101.3001.5002&articleId=10830645&d=1&t=3&u=b2b4c7e770ca44bbafa37d6f40aad9c1)
4555

被折叠的 条评论
为什么被折叠?



