------- android培训、java培训、期待与您交流! ----------
【collection】
【List】
元素是有序的(加入的顺序),可以重复。因为该集合的集合体有索引。
①--ArrayList 底层使用的是数组数据结构 特点:查询速度快,但是增删慢,线程不同步,线程不安全,效率高。特点:轻量级的用数组实现的(可以用下标进行删除和查 查询快,增删慢(实现搜索引擎的最优选择)②--LinkedList 底层使用的是链表数据结构 特点:但是查询慢(实现栈的最优选择) 特有的addFirst()、removeFirst()方式
③--Vector 底层是数组数据结构,和ArrayList 功能一样 但线程同步(安全) 增删查询都比较慢,被ArrayList替代
枚举是Vector的特有取出方式,类似迭代器,但方法名称过长
【Set】
元素无序,元素不可以重复。
①--Set:元素是无序的(存入和取出的顺序不一定一致,)元素不可以重复
②--HashSet:底层数据结构是哈希表;线程非同步
③--TreeSet;可以对Set集合中的元素进行排序 底层数据结构式二叉树
保证元素唯一些的依据重写compareTo方法并return 0
Hashset保证元素唯一的逻辑
现在通过写一段代码来验证HashSet,对存入的对象时如何处理的
思路:
1 新建一个HashSet,用来存储对象
2 用add方法存入一个新的对象,这个对象有自己的属性:name和age
3 通过查阅资料知道,HashSet在存入时如果 hash值相等时,就会调用Object的 equals 方法比较两个元素是否相等,
具体 equals 比的是什么,要看具体的实现,但这里我们可以重写equals方法来自定义一个我们的比较方法。
4 为了验证3的结论,我们通过public int hashCode方法,让对象拥有相同的哈希值。猜测:如果哈希值相同就会表用equals方法
所以在public boolean equals(Object obj)中的“哈希值相同”就会打印出来。
5 当哈希值相同了,我们可以自定义equals比较方法,如将姓名相同的视为一个人而不考虑年龄;或者将姓名年龄相同的视为一个人
问题:HashSet 判断元素是否存在也依赖于哈希值和equals方法
思路:用HashSet的contains方法判断person("a1",27)是否存在
猜测:
①在自定义的equals()方法中只判断了姓名的时候person("a1",30)存在!
②在自定义的equals()方法中判断了姓名和年龄的时候person("a1",30)不存在!
class HashSetDemo
{
public static void main(String[] args)
{
HashSet sh = new HashSet();
sh.add(new person("a1",22));
sh.add(new person("a1",29));
sh.add(new person("a1",27));
sh.add(new person("a4",24));
sh.add(new person("a5",25));
Iterator it = sh.iterator();
while (it.hasNext())
{
Object obj = it.next();
//System.out.println(obj.name);
}
System.out.println(sh);//打印结果[person3c,person3c,person3c]
System.out.println(sh.contains(new person("a1",30)));
//当在equals()方法中只判断了姓名是否相同。所以在判断的时候就忽略了年龄。打印结果 ture
//当在自定义的equals()方法中判断了姓名和年龄的时候person("a1",30)不存在。打印结果 false
}
}
class person
{
int age;
String name;
person(String name,int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)//复写Object的equals 方法。
{
person p = (person) obj;
System.out.println("哈希值相同");
return this.name.equals(p.name);//&&this.age==p.age; //自定义比较的方法
//理解:这里的this代表HashSet中已经存在的每一个对象,p代表存入的对象。
}
public int hashCode()//为对象设定哈希值,如果不设定,对象的哈希值就不相同,则equals方法就不会调用了。
{
return 60; //设定每个对象的哈希值为60,而equals方法中的“哈希值相同”就会打印了。
}
public String setName(String name)
{
this.name = name;
return name;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
结论:在使用HashSet时,我们可以按照需求通过复写和equals()方法来自定义存储方式。
HashSet 在判断元素是否存在也依赖于hashCode()和equals()方法。
特例:容器中装容器
每个Collecton都有一个addAll()方法,可以把一个集合完全装载到另外一个集合里面:例如:
Setset=newSet();Listls=newList();
Ls.addAll(set);//把Set装载在list里面。
Collections(工具类)
跟Collection没有关系,主要提供一些操作集合对象的方法。
List 底层使用的是数据结构,可以用迭代器遍历
迭代器(Iterator和ListIterator)
迭代器是是一种对象跟容器紧密结合,不同的容器,它的迭代器不同,但是,他们有共同的目标,就是可以通过该迭代器,来遍历访问这个容器里面的元素。
如果在迭代过程中要对元素进行增删功能就不能用容器的方法操作,那样会报错,只能用迭代器的方法操作,但不能用Iterator只能用迭代器的子接口ListIterator来操作。
import java.util.*;
class listdemo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java4");
al.add("java5");
sop(al);
Iterator it = al.iterator();
//ListIterator li = al.listIterator();//Iterator子接口ListIterator
while (li.hasNext())//(it.hasNext())
{
Object obj = li.next();//it.next()
if (obj.equals("java2"))
{
/*
al.add("java xxx000");//迭代过程中添加元素失败
it.remove();//用迭代器的方法,当迭代到“java2”的时候删除
这里的迭代器有局限性,没有添加的操作,只能用listIteraror
li.add("java9");//在迭代到java2的时候添加“java9”
li.set("java 007");//修改
*/
}
}
sop(al);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
加上泛型的迭代器及TreeSet的第一种排序方法:自定义比较器
class student
{
String name;
student(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class advstudent extends student
{
advstudent(String name)
{
super(name);
}
public String getName()
{
return name;
}
}
class comp implements Comparator<student>//自定义比较器
{
public int compare(student s1,student s2)//覆盖compare方法
{
return s1.getName().compareTo(s2.getName());
}
}
class studentdemo
{
public static void main(String[] args)
{
TreeSet<student> ts = new TreeSet<student>(new comp());
ts.add(new student("java1"));
ts.add(new student("java2"));
ts.add(new student("java3"));
ts.add(new student("java4"));
ts.add(new student("java5"));
print(ts);
TreeSet<advstudent> ts1 = new TreeSet<advstudent>(new comp());
ts1.add(new advstudent("java...01"));
ts1.add(new advstudent("java...02"));
ts1.add(new advstudent("java...03"));
ts1.add(new advstudent("java...04"));
print(ts1);
}
public static void print(TreeSet<? extends student> qqq)//传入带泛型限定的TreeSet
{
Iterator<? extends student> it = qqq.iterator();//迭代器加上了泛型,可以接受student及其子类
while (it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
TreeSet第二种排序方法:让元素具备比较性,复写compareto方法
public class Student implements Comparable{
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int compareTo(Object obj) {
if (obj instanceof Student)
{
Student student = (Student)obj;
if (this.num > student.getNum())
{
return 1;
}
else if (this.num == student.getNum())
{
return 0;
}
else
{
return -1;
}
}
return 0;
}
}
由集合排序引出的两个比较接口:
一个是Comparable:覆盖compareTo方法;(java.lang包中)
一个是Comparator:覆盖compare方法。(java.util包中)
使用集合的技巧:
看到Array就是数组结构,有角标,查询速度很快。
看到link就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();
看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。
看到tree就是二叉树,就要想到排序,就想要用到比较。
其实无论是自定义比较器还是让元素具备比较功能,都是集合底层在调用compare()或者compareto()方法,并使用return的数据来进行判定。
【MAP】
1:Map定义(key--value):通过一个key值得到一个value,一般用作八种基本类型和字符串作为一个map集合的key值,key值不能重复
2:SortedMap:一般是按照key值得升序排序,如果需要自己规定,那么就需要key对象所对应的类覆盖comparable接口。
3:HashMap(实现类):对key保持唯一。如果用自定义的key,那么就要覆盖hashclode()和equals()方法;
4:HashTable:(实现类):
5:二者比较:
HashMap轻量级的,线程不安全,键值可以有空指针。
HashTable:重量级的,线程安全的,键值都不能有空指针。
6:properties:
主要是用来存取配置文件的信息。本质上两个参数都是一个字符串型的。
获取map中的元素:
原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。
把map集合转成set的方法:
Entry就是Map接口中的内部接口;
为什么要定义在map内部呢?entry是访问键值关系的入口,是map的入口,访问的是map中的键值对。
--------------------------------------------------------
取出map集合中所有元素的方式一:entrySet()方法。
取出map集合中所有元素的方式二:keySet()方法。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class mapdemo {
public static void main(String[] args){
Map map = new HashMap();
map.put("1", "abc");
map.put("2", "abc");
map.put("3", "abc");
map.put("4", "abc");
/*第一种取出方式
Set set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext())
{
Map.Entry entry = (Map.Entry)it.next();
System.out.println(entry.getKey()+"..."+entry.getValue());
}*/
//第二种取出方式
Set keys = map.keySet();
if (keys !=null);
Iterator it = keys.iterator();
while (it.hasNext())
{
Object obj = it.next();
System.out.println(map.get(obj));
}
}
}
资料:
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。 从概念上而言,您可以将 List 看作是具有数值键的 Map。 而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。