-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
1、Set
Set是Collection接口的子接口,此集合中不能存放重复元素,对于比较方式是根据他们的底层结构决定的,常见的子类有:HashSet和TreeSet
2、无序性
Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
Set集合的读取只有一种方式就是迭代器Iterator
public class HashSetDemo { public static void main(String[]args) { HashSet set = new HashSet();// HashSet对象 set.add("java01"); set.add("java02");// 添加元素 set.add("java03"); Iterator it = set.iterator();// 迭代器读取数据 while (it.hasNext()) { System.out.println(it.next()); } } }结果:java02java03java01
3、HashSet
HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
HashSet是如何保证元素唯一性的呢?
答:是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
4、HashSet判断和删除的依据
HashSet hs=new HashSet();
hs.contains(obj);
hs.remove(obj);
注意:对于判断元素是否存在,以及删除等条件,依赖的是元素的hashCode和equals方法。
5、TreeSet
TreeSet本身对元素记性排序,要是自定的类,那么要是此类对象存数TreeSet中,那么就必须是S自定义的类本身具备比较性,那么据必须实现接口Comparable,并重写方法compareTo()方法,底层数据结构是二叉树compareTo()返回值是整数,如果小于0,那么此对象就小于比较的对象,等于0,那么此对象就等于比较的对象,如果大于0,那么此对象就大于比较的对象。
6、排序方式
排序的第一种方式:让元素自身具备比较性。
实现方法:元素需要实现Comparable接口,覆盖compareTo方法。
也种方式也成为元素的自然顺序,或者叫做默认顺序。
排序的第二种方式:让集合自身具备比较性。
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
实现方法:在集合初始化时,就有了比较方式。
例1:
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);
}
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
例2:
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num==0)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
7、泛型
jdk1.5版本之后出现新特性,用于解决安全问题的,是一个安全机制。
例如:只能存储String的ArrayList
ArrayList<String> AL=new ArrayList<String>();
//取出的时候也要用泛型
Iterator<String> It=AL.iterator();
while(It.hasNext())
{
取出元素:It.next();
}
好处:将运行时期的出现的问题ClassCastException转移到了编译时期,方便程序员解决问题,让运行时的问题减少,安全;避免了强制转换麻烦。
8、泛型使用
泛型格式:通过<>来定义要操作对象的引用类型。
在使用java时,什么时候可以使用泛型呢?
通常在集合框架中很常见,只要见到<>就可以使用。
其实<>是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>即可。
泛型只能接受引用数据类型。
9、泛型类
没有泛型时的工具类:
class Tool
{
private Object obj;
public void setObject(Object obj)
{
this.obj=obj;
}
public Object getObject()
{
return obj;
}
}
泛型出现后的工具类:
class Tool<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q=q;
}
public QQ getObject()
{
return q;
}
}
这就是传说中的泛型类。
泛型类的使用:当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。
10、泛型方法
class Demo<T>
{
public void show(T t)//该方法的参数类型随着该类的泛型走
{
}
public <Q> void print(Q q)//泛型方法,该方法的参数类型是Q
{
}
}
泛型类定义的泛型在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所以要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定,那么就可以将泛型定义在方法上。
11、静态泛型方法
特殊之处:静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
public static <W> void method(W w)
{
}
12、泛型接口
泛型定义在接口上
interface Inter<T>
{
void show(T t);
}
class InterSon<T> implements Inter<T>
{
public void show(T t)
{
}
}
13、泛型限定
通用的泛型:如ArrayList<?> al;
public static <T> void print(ArrayList<T> al)
{
Iterator<T> it=al.iterator();
while(it.hasNext())
{
打印;
}
}
通用泛型可以把上面的T换成?号。但要注意传入对象的特有方法。
泛型限定:
?:通配符,也可以理解为占位符。
<? extends E>:可以接受E类型或E的子类型,这是上限固定。
<? super E>:可以接受E类型或者E的父类型。这是下限固定。