集合与泛型
1、集合
集合对象是内存中的一个容器对象,用来方便的存贮批量的数据,集合中的数据在没有持久化,程序运行结束后,数据将消失。在java语言中,设计的集合主要为3大类
Set集合:实现Set接口的集合类称为Set集合;
List集合:实现List接口的集合类称为List集合;
Map集合:实现Map接口的集合类称为Map集合
java对集合设计的相关接口与类放在:java.util包中,在我们使用集合时,需要导入对应的集合类或者接口
集合中只能放引用类型数据,不能放基本数据类型,如果要放,请使用基本数据类型的包装类型
Collection是Set、List、Queue三个集合共同的接口
2、Set集合
Set集合特性:不包含重复元素,通过调用元素的equals方法实现判断两个元素是不是同一个元素
public interface Set<E> extends Collection<E>
Set接口的实现类:HashSet、TreeSet
1.HashSet
基于hash算法决定元素在集合中的存放位置,HashSet存取效率非常高
熟练Set集合的基本操作API:添加、删除、获取元素、集合大小,清空集合等获取集合元素:
1、转成数组
Set接口的实现类:HashSet、TreeSet
1.HashSet
基于hash算法决定元素在集合中的存放位置,HashSet存取效率非常高
熟练Set集合的基本操作API:添加、删除、获取元素、集合大小,清空集合等
获取集合元素:
1、转成数组
Set set = new HashSet();
set.add(1);
set.add(2);
set.add(3);
Object[] arr = set.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
2、迭代器(Iterable)
迭代器:
- 一个递归获取集合元素的方式 ,需要集合实现Iterable接口,此接口定义了迭代访问集合元素的方法
- 迭代器是一个指针对象,默认指向集合第一个元素前,通过调用
hashNext()
方法可以移动迭代器 -
// 迭代器:Iterable
Iterator<T> iterator(); // 实现Iterable接口的方法,就能得到的一个迭代器对象// Iterator的主要方法
boolean hasNext(); // 如果仍有元素可以迭代,则返回true
E next(); // 返回迭代的下一个元素
void remove(); // 从迭代器指向的collection中移除迭代器返回的最后一个元素// 通过迭代器获取Set集合元素
Set set = new HashSet();
set.add(1);
// ....
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
} -
对Set集合,如果放到集合里的是一个对象,且当对象的某个属性一致时,判断为同一个属性,如何操作?
Set集合默认是调用对象的equals方法比较,此时,已不能满足我们的业务需要
解决方法:根据新的业务重写equals方法, 此时还要重写hashcode方法
下面的例子是当tel相同时视为同一个对象:
User类:
@Data
public class User {private int id;
private String name;
private String tel;
@Override
public int hashCode(){
// 这里重写了hashCode方法,将tel作为hashCode的值
return Integer.parseInt(tel);
}@Override
public boolean equals(Object o){
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
// 根据Tel是否相同判断是否为同一个人
if (tel.equals(user.getTel())) {
return true;
}
return Objects.equals(id, user.id);
}
} - 测试:
-
public static void main(String[] args){
Set set = new HashSet();User u1 = new User();
u1.setId(1);
u1.setName("张三");
u1.setTel("183");User u2 = new User();
u2.setId(2);
u2.setName("李四");
u2.setTel("183");set.add(u1);
set.add(u2);// 可以看到,只输出了1,证明只有1个对象存进去了
System.out.println(set.size());Iterator it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}}
-
2.TreeSet
Set接口的第2个实现类,TreeSet相对于HashSet,多了一个排序的功能
排序方法:使用元素的自然顺序对元素进行排序
元素的自然顺序:此元素实现Comparable接口,当将元素放到TreeSet集合中,TreeSet集合就根据Comparable接口定义的比较规则来比较元素
// 返回值为整型: 为0 表示两个元素相等,大于0 表示大于,小于0 表示小于
public interface Comparable{
int compareTo(T o)
}如果放到TreeSet集合中的元素没有实现自然排序,则意味会出异常。在JDK中,8种基本数据类型的包装类型和字符串都实现了此接口
-
如果在集合中放其它类型的元素,必须手动实现Comparable接口,并实现接口中定义的compareTo方法
-
@Data
public class User implements Comparable<User>{private int id;
private String name;
private String tel;
@Override
public int compareTo(User o) {
// 根据id排序
int compare = Integer.compare(this.id, o.getId());
if (compare == 0) {
// 若id相同,则根据名字排序
return this.name.compareTo(o.getName());
}
return compare;
}
}