java学习(11)

java学习(11)

这篇接着上篇来写Collection集合的子接口Set接口和它的几个实现类

1.Set
 1.1常用方法:Set里的常用方法和Collection集合的方法基本相同,上篇已经进行了解说,这里不做详细叙述了。

1.2HashSet:Set接口的实现类
特点:元素顺序:元素唯一,但是无序

示例:
  //创建一个HashSet集合,用泛型限定,String
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("to");
hs.add("be");
hs.add("or");
hs.add("not");
hs.add("to");
hs.add("be");
//遍历
for (String string : hs) {
System.out.print(string+ " ");
}

结果:

分析:1)运行结果不能保证顺序,即会出现顺序不同的结果

   2)元素唯一,相同的元素只能存储进去一个
 2.2如何保证元素的唯一性:

在源码部分有:
 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {...}

左边:e.hash == hash 比较对象的哈希值。
右边:((k = e.key) == key || key.equals(k))
1)(k = e.key) == key 比较对象的地址值。
2)key.equals(k) 比较的是对象的内容是否相同。默认情况下比较的是地址值
 
HashSet的底层数据结构是哈希表。而哈希表依赖两个方法:hashCode()和equals()来保证元素的唯一性
执行流程:
1)首先判断哈希值是否相同,如果不同,就直接添加到集合。
2)如果相同,继续执行equals(),看其返回值,
3)如果是false,就直接添加到集合。
4)如果是true,说明元素重复不添加。
1.3TreeSet:Set接口的实现类
 1.3.1 元素顺序:使用元素的自然顺序对元素进行排序,或者根据创建 set时提供的 Comparator进行排序,具体取决于使用的构造方法。

示例:

//创建一个TreeSet集合,限定为Integer
TreeSet<Integer> ts = new TreeSet<Integer>();
//添加元素
ts.add(21);
ts.add(13);
ts.add(32);
ts.add(5);
ts.add(26);
//遍历
for (Integer integer : ts) {
System.out.println(integer);
}

结果:


分析:这里可以很明看到对于输入的整型数字,在输出时是进行了排序的顺序输出。同理,对于字符串也会进行排序,是按照字符串首字母的ASCII码排序的。

 1.3.2 底层算法:二叉树
 1.3.3 元素要求, 加入自定义JavaBean

自然排序:这里创建一个Dog类,创建对象进行示例:

Dog类:

public class Dog implements Comparable<Dog>{

private String name;
private int age;

public Dog() {
super();
// TODO Auto-generated constructor stub
}

public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}



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;
}



@Override
public String toString() {
return "Dog [name=" + name + ", age=" + age + "]";
}


@Override
public int compareTo(Dog d) {
int num = this.age - d.age;
int num2 = num == 0?this.name.compareTo(d.name):num;
return num2;
}


}

TreeSet测试类:

public class TreeSetTest {

public static void main(String[] args) {
//创建一个TreeSet集合
TreeSet<Dog> ts = new TreeSet<Dog>();
//创建Dog类对象
Dog d1 = new Dog("jinmao", 2);
Dog d2 = new Dog("erha", 1);
Dog d3 = new Dog("chaiquan", 3);
Dog d4 = new Dog("duantui", 2);
//添加元素
ts.add(d1);
ts.add(d2);
ts.add(d3);
ts.add(d4);
//遍历
for (Dog dog : ts) {
System.out.println(dog);
}
}
}

结果:


分析:这里的Dog类实现了Comparable接口,用的是自然排序,按照年龄进行排序,年龄相同的按照名字首字母的ASCII码进行排序。

比较器排序:这里写一个Student类,进行代码示例:

Student类:

public class Student {


private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}

}

TreeSetTest测试类:

public class TreeSetTest {


public static void main(String[] args) {
//创建一个TreeSet集合,使用比较器排序
TreeSet<Student> st = new TreeSet<Student>(new Comparator<Student>() {


@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num == 0?s1.getName().compareTo(s2.getName()):num;
return num2;
}
});
//创建Student对象
Student s1 = new Student("Bob", 12);
Student s2 = new Student("Jak", 11);
Student s3 = new Student("Kio", 15);
Student s4 = new Student("Lin", 12);
//添加元素
st.add(s1);
st.add(s2);
st.add(s3);
st.add(s4);
//遍历
for (Student student : st) {
System.out.println(student);
}
}
}

结果:


分析:这里Student类实现了Comparator接口,使用匿名内部类,按照年龄进行排序,年龄相同的按照名字首字母的ASCII码进行排序。

1.4HashSet与TreeSet的相同点与不同点
相同点:单列集合,元素不可重复
不同点:
1)底层存储的数据结构不同
    HashSet底层用的是HashMap哈希表结构存储,而TreeSet底层用的是TreeMap树结构存储
2)存储时保证数据唯一性依据不同
   HashSet是通过复写hashCode()方法和equals()方法来保证的,而TreeSet通过Compareable接口的compareTo()方法来保证的
3)有序性不一样:HashSet无序,TreeSet有序


2.Map:

将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
2.1 Map接口中的方法
A:删除功能
void clear():移除集合中的所有键值对元素
V remove(Object key):根据键移除键值对元素,并返回值
B:判断功能
   boolean containsKey(Object key):判断集合中是否包含指定的键
   boolean containsValue(Object value):判断集合中是否包含指定的值
   boolean isEmpty():判断集合是否为空
   C:获取功能
  Set<Map.Entry<K,V>> entrySet():获取键值对对象的集合,遍历键值对对象,
            利用getKey(),getValue()取出键和值(理解即可)
V get(Object key):根据键获取值
  Set<K> keySet():获取所有的键
  Collection<V> values():获取所有的值
  D:添加功能
  V put(K key,V value):集合添加键值对
  E:长度功能
  int size():键值对对数。

示例:

//创建一个Map集合
Map<Integer,String> map = new HashMap<Integer,String>();
//添加功能
//V put(K key,V value):集合添加键值对
map.put(1, "小明");
map.put(2, "小红");
map.put(3, "小玲");
map.put(4, "小梅");
//Set<K> keySet():获取所有的键
//V get(Object key):根据键获取值
Set<Integer> keySet = map.keySet();
//遍历一
for (Integer key : keySet) {
System.out.println(key+" "+map.get(key));
}
System.out.println("===========");
//遍历二
//Set<Map.Entry<K,V>> entrySet():获取键值对对象的集合,遍历键值对对象,
//利用getKey(),getValue()取出键和值
Set<Entry<Integer, String>> entryset = map.entrySet();
for (Entry<Integer, String> entry : entryset) {
System.out.println(entry.getKey()+" "+entry.getValue());
}

结果:


分析:这里创建了Map集合,并且添加了元素,使用了部分成员方法,使用了两种方法进行遍历,其他方法不进行详细叙述。

2.2 HashMap
 2.2.1元素顺序:元素顺序不可预测
 2.2.2底层算法:哈希算法
 2.2.3对键没有要求
注意:键是同一个对象的时候要把之前存入的元素挤出去,想要实现这样的效果的话,需要重写javabean里面的hashCode()和equals()方法。

这里创建一个Dog类,并且重写hashCode()和equals()进行示例:

Dog类:

public class Dog {


private String name;
private int age;
public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Dog() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Dog [name=" + name + ", age=" + age + "]";
}

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;
}
@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;
Dog other = (Dog) 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;
}

}

HashMapTest测试类:

public class HashMapTest {

public static void main(String[] args) {
//创建HashMap集合
HashMap<Dog, String> hmp = new HashMap<Dog,String>();
//创建Dog类对象
Dog d1 = new Dog("二哈", 2);
Dog d2 = new Dog("金毛", 1);
Dog d3 = new Dog("柴犬", 3);
Dog d4 = new Dog("二哈", 2);
//添加元素
hmp.put(d1, "拆迁大队长");
hmp.put(d2, "金子");
hmp.put(d3, "阿黄");
hmp.put(d4, "拆迁大队长");
//遍历
Set<Dog> keySet = hmp.keySet();
for (Dog key : keySet) {
System.out.println(key+" "+hmp.get(key));
}
}
}

结果:

分析:Dog类重写了hashCode()和equals()的方法,所以键是相同对象,后面的会覆盖前面的元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值