Set接口_HashSet的用法
Set接口
Set接口的特点:唯一,无序
HashSet的用法
package cn.xjion.pro09;
import java.util.HashSet;
import java.util.Iterator;
public class TestHashSet {
public static void main(String[] args) {
// HashSet底层数据结构是使用的hash表,主要结构为数组+链表
// 创建集合对象
HashSet hs = new HashSet<>();
hs.add("java");
System.out.println(hs.add("world"));
hs.add("Hello");
System.out.println(hs.add("world"));
System.out.println("集合中元素个数:"+hs.size());
System.out.println(hs);
System.out.println(hs.contains("java")+"\t\t"+hs.contains("java1"));
System.out.println("————————————————————————————————");
// 使用迭代器遍历元素
for(Iterator ite = hs.iterator();ite.hasNext();){
System.out.println(ite.next());
}
}
}
Person
package cn.xjion.pro09;
// Person类实现Person型的Comperable接口
public class Person implements Comparable<Person>{
// 属性
private String name;
private int age;
// get,set方法
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;
}
// 带参构造方法
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//空构造器
public Person() {
super();
// TODO Auto-generated constructor stub
}
// 重写hashCode和equals方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 重写toString
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
// 重写compareTo方法
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return 0;
}
}
测试:
package cn.xjion.pro09;
import java.util.HashSet;
public class TestPerson {
public static void main(String[] args) {
HashSet hs = new HashSet<>();
// 创建4个Person类型的对象
Person p1 = new Person("jion", 20);
Person p2 = new Person("lqimi", 22);
Person p3 = new Person("xxxjion", 20);
Person p4 = new Person("jack", 30);
// 添加到集合中
hs.add(p1);
hs.add(p2);
hs.add(p3);
hs.add(p4);
System.out.println(hs);
}
}
HashSet的底层实现_JDK源码分析
package cn.xjion.pro09;
import java.util.HashSet;
import java.util.Iterator;
public class TestHashSet {
/**
* HashSet底层源码分析
* private transient HashMap<E,Object> map;
* private static final Object PRESENT = new Object();
* public HashSet() {
map = new HashMap<>(); //创建HashSet时,底层创建的是一个HashMap对象
}
public boolean add(E e) {
key-->e,value-->PRESENT,是一个Object类型的对象
map集合中的所有value都是统一的Object类型对象
return map.put(e, PRESENT)==null;
}
public int size() {
return map.size();
}
public boolean contains(Object o) {
return map.containsKey(o);//在map集合中判断key是否存在
}
public Iterator<E> iterator() {
return map.keySet().iterator(); //获取map集合中所有的key的集合,再得到迭代器对象
}
HashSet使用了HashMap的数据结构,
底层都是哈希表(顺序表+链表)
*
*/
public static void main(String[] args) {
//HashSet底层数据结构使用的是hash表,主结构数组+链表
//创建集合对象
HashSet hs = new HashSet();
hs.add("hello");
System.out.println(hs.size());
System.out.println(hs.contains("hello"));
//使用迭代器遍历元素
Iterator ite = hs.iterator();
while (ite.hasNext()) {
System.out.println(ite.next());
}
}
}
TreeSet的使用_JDK源码分析
底层数据结构
TreeMap(Key,唯一的升序的),底层数据结构:红黑树,而且TreeMap中的key实际上就是一个TreeSet,如果使用自定义对象作为key,要求必须具备比较规则。
使用TreeMap要求使用内部比较器或者外部比较器
使用:
比较器
package cn.xjion.pro09;
import java.util.Comparator;
public class ComCharactorAndAge implements Comparator{
public int compare(Object o1,Object o2) {
Person p1 = (Person)o1;
Person p2 = (Person)o2;
if (p1.getName().compareTo(p2.getName())<0){
return -1;
}else if(p1.getName().compareTo(p2.getName())>0) {
return 1;
}else {
return p1.getAge() - p2.getAge();
}
}
}
Person
package cn.xjion.pro09;
// Person类实现Person型的Comperable接口
public class Person implements Comparable<Person>{
// 属性
private String name;
private int age;
// get,set方法
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;
}
// 带参构造方法
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//空构造器
public Person() {
super();
// TODO Auto-generated constructor stub
}
// 重写hashCode和equals方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 重写toString
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
// 重写compareTo方法
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return 0;
}
}
public class TestTreeSet {
/**
* TreeSet的底层使用的是TreeMap -->红黑树
* TreeSet JDK源码分析
* private transient NavigableMap<E,Object> m; //一个接口,间接继承了Map
* private static final Object PRESENT = new Object();
* public TreeSet() {
this(new TreeMap<E,Object>());//创建了一个TreeMap的对象
}
//调用的本类中的带参构造方法
TreeSet(NavigableMap<E,Object> m) {
this.m = m; //接口new 实现类
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator)); //调用了本类中的带参构造方法
}
public boolean add(E e) {
return m.put(e, PRESENT)==null; //传入的元素作为Map中的key,统一的值为Object类型的对象
}
public int size() {
return m.size();
}
*/
public static void main(String[] args) {
ComCharactorAndAge comc = new ComCharactorAndAge();
TreeSet ts = new TreeSet(comc);
//创建集合对象
//TreeSet ts = new TreeSet();
//创建Person对象
Person p1 = new Person("marry",20);
Person p2 = new Person("lili",19);
Person p3 = new Person("jack",20);
Person p4 = new Person("marry",18);
//添加到集合中
ts.add(p1);
ts.add(p2);
ts.add(p3);
ts.add(p4);
System.out.println("集合中元素的个数:" + ts.size());
System.out.println(ts);
}
}
迭代器
由来:
使用迭代器遍历集合
package cn.xjion.pro09;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
public class Test {
/**
* public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
int i = cursor;
Object[] elementData = ArrayList.this.elementData;
cursor = i + 1;
return (E) elementData[lastRet = i]; //根据索引获取元素
}
*
*/
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
al.add("java");
al.add("world");
Iterator<String> ite = al.iterator();
while (ite.hasNext()) {
System.out.println(ite.next());
}
HashSet<Integer> hs = new HashSet<Integer>();
hs.add(456);
hs.add(123);
hs.add(789);
Iterator<Integer> ite2 = hs.iterator();
while (ite2.hasNext()) {
System.out.println(ite2.next());
}
}
}
迭代器遍历Map
ListIterator接口
ListIterator是对Iterator接口的扩展,用于解决并发修改的异常。
package cn.xjion.pro09;
import java.util.ArrayList;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
al.add("world");
al.add("java");
ListIterator<String> ite = al.listIterator();
while (ite.hasNext()) {
String str = ite.next();
if ("world".equals(str)) {
ite.add("sql");
}
}
System.out.println(al);
System.out.println("逆向遍历元素");
while (ite.hasPrevious()) {
System.out.println(ite.previous());
}
}
}
遍历Map
package cn.xjion.pro09;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
public class TestMap {
public static void main(String[] args) {
HashMap<String,Integer> hm = new HashMap<String,Integer>();
hm.put("hello", 123);
hm.put("world",456);
hm.put("java", 567);
//第一种
Set<String> set = hm.keySet();
for (String str : set) {
System.out.println(str + "\t" + hm.get(str));
}
//第二种遍历
Set<Entry<String,Integer>> entry = hm.entrySet();
for (Entry<String, Integer> ent : entry) {
System.out.println(ent.getKey() + "\t" + ent.getValue());
}
}
}