黑马程序员_java_集合总结(下)

来源:互联网 发布:脸部比例测试软件 编辑:程序博客网 时间:2024/06/06 03:30
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------






五、Set接口
    Set接口和List接口一样,同样继承Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
    Set接口取出方式只有一种,迭代器。
(1)HashSet集合
底层数据结构是哈希表,线程是不同步的。无序,不可重复,高效。


HashSet数组遍历:
public class HashSetDemo {
public static void main(String[] args) {
// 创建集合对象
HashSet<String> hs = new HashSet<String>();


// 创建并添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("java");


// 遍历
for (String s : hs) {
System.out.println(s);
}
}
}






HashSet存储自定义对象。(案例)
  需求:我们认为一个对象如果成员变量值都相同,则为同一个对象。
 
  请思考:
  A:哪里出问题了
  通过简单的分析,我们知道了在add方法出问题了。
  B:怎么解决
  看源码
  通过看源码:我们知道,最终的操作跟如下这个判断相关
  if(e.hash == hash && ((k = e.key) == key || key.equals(k)))
  {
  唯一。
  }
 分析条件:
  A:这个判断跟对象的hashCode()方法相关。
  B:这个判断跟equals()方法相关。
 
 
 总结:
  HashSet如何保证元素的唯一性的呢?
  HashSet的底层数据结构是哈希表。
  它依赖两个方法,hashCode()和equals()。
  顺序:
  首先,判断对象的hashCode()值是否相同。
  相同:
  继续走equals()。看返回值是true还是false
  A:如果是true,说明有元素重复。该元素不添加到集合。
  B:如果是false,说明元素不重复,该元素添加到集合。
  不同:就直接添加到集合中了。


public class HashSetDemo2 {
public static void main(String[] args) {
// 创建集合对象
HashSet<Student> hs = new HashSet<Student>();


// 创建元素对象
Student s1 = new Student("AAA", 26);
Student s2 = new Student("BBB", 46);
Student s3 = new Student("CCC", 20);
Student s4 = new Student("DDD", 26);
Student s5 = new Student("EEE", 36);
Student s6 = new Student("FFF", 16);


// 添加元素
hs.add(s1);
// hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
hs.add(s5);
hs.add(s6);


// 遍历
for (Student s : hs) {
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
(2)LinkedHashSet集合
LinkedHashSet继承 HashSet集合。
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。) 


(3)TreeSet集合
对Set集合中的元素的进行指定顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。


(输入后按默认进行排序,数字按大小,字符串则:依次数字0~9,字母A~Z,a~z
//集合中的元素进行比较时是调用compareTo()方法的,而该方法是在Comparable中定义的,因此想要对集合中的元素进行排序,就必须实现Comparable接口。
compareTo重写:
public int compareTo(Object obj) {
Student s = (Student)obj;
if (this.age-s.age>0) {
return 1;
}
if (this.age-s.age==0) {
return this.name.compareTo(s.name);
}
return -1;
}

第二种比较排序的方法,创建匿名内部类
public class TreeSetDemo {
public static void main(String[] args) {
// 创建集合对象
// public TreeSet(Comparator comparator)
// Comparator c = new MyComparator();
// TreeSet<Student> ts = new TreeSet<Student>(c);
// 两句写一句
// TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());


// 匿名内部类
TreeSet<Student> ts = 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 s1 = new Student("AAA", 52);
Student s2 = new Student("BBB", 60);
Student s3 = new Student("CCC", 44);
Student s4 = new Student("DDD", 34);
Student s5 = new Student("AAA", 26);
Student s6 = new Student("EEE", 36);
Student s7 = new Student("CCC", 26);
Student s8 = new Student("AAA", 26);


// 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
ts.add(s8);


// 遍历
for (Student s : ts) {
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
(4)登录系统用户实现类(集合)
public class UserDaoImpl implements UserDao {
private static ArrayList<User> array = new ArrayList<User>();


@Override
public boolean isLogin(String username, String password) {
boolean flag = false;


// 遍历集合,获取每一个用户,如果存在,就修改标记为true
for (User u : array) {
if (u.getUsername().equals(username)
&& u.getPassword().equals(password)) {
flag = true;
break;
}
}


return flag;
}


@Override
public void regist(User user) {
array.add(user);
}
}


六、Map双列集合
(1)Map中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。
(2)Map中的键必须是唯一的,不能重复。如果存储了相同的键,后储存的值则会覆盖原有的值,简而言之就是:键相同,值覆盖。
1,添加。
 put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null。
 void putAll(Map);
2,删除。
void clear():清空
value remove(key) :删除指定键。
3,判断。
boolean isEmpty():
boolean containsKey(key):是否包含key
boolean containsValue(value) :是否包含value
4,取出。
int size():返回长度
value get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null值的。
*Set<K> keySet()  获取键的集合,返回此映射中包含的键的 Set 视图
*Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
Collection values():获取map集合中的所有的值。
5,想要获取map中的所有元素:
原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。
方法一:
Map map = new HashMap();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
Set keySet = map.keySet();
Iterator it = keySet.iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = map.get(key);
System.out.println(key + "  " + value);
}
方法二:Map map = new HashMap();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
Set entrySet = map.entrySet();
Iterator it = entrySet.iterator();
while(it.hasNext()){
Map.Entry entry =(Map.Entry)(it.next());
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + "  " + value);
}
七、TreeMap集合
TreeMap集合是用来存储键值映射关系的,其中不允许出现重复的键,并通过二叉树原理以一种某种的顺序排列。
遍历:
方法一:同之前的
方法二:自定义比较器
Tree tm= new TreeMap(new MyComparator());//创建map集合
map.put("1", "value1");//存储键和值
map.put("2", "value2");
map.put("3", "value3");
Set keySet = tm.keySet();//获取键的集合
Iterator it = keySet.iterator();//迭代键的集合
while (it.hasNext()) {//循环判断是否有下一个元素
Object key = it.next();//获取每个键
Object value = tm.get(key);//获取每个键的值
System.out.println(key + "  " + value);//打印输出
//自定义比较器
class MyComparator implements Comparator{ 
public int compare(Object obj1,Object obj2){
String id1=(String) obj1;
String id2=(String) obj2;
return id2.compareTo(id1);
}
}
八、HashMap集合
底层是哈希表数据结构,是线程不同步的。可以存储null键,null值。替代了Hashtable.
HashMap遍历
遍历:
方法一:
Map map = new HashMap();//创建map集合
map.put("1", "value1");//存储键和值
map.put("2", "value2");
map.put("3", "value3");
Set keySet = map.keySet();//获取键的集合
Iterator it = keySet.iterator();//迭代键的集合
while (it.hasNext()) {//循环判断是否有下一个元素
Object key = it.next();//获取每个键
Object value = map.get(key);//获取每个键的值
System.out.println(key + "  " + value);//打印输出
}
方法二:
Map map = new HashMap();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
Set entrySet = map.entrySet();//获取键值对关系的集合
Iterator it = entrySet.iterator();
while(it.hasNext()){
Map.Entry entry =(Map.Entry)(it.next());//获取集合中键值对的映射关系
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + "  " + value);
}
获取所有值:
Map map = new HashMap();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
Set entrySet = map.entrySet();
Collection values = map.values();
Iterator it = values.iterator();
while(it.hasNext()){
Object values = it.next();
System.out.println(value);

}





九、LinkedHashMap集合
LineHashMap是HashMap的子类,和LinkedList一样也使用双向列表来维护内部元素的关系,使Map元素迭代的顺序与存入的顺序一致。
遍历方法与之前相同


十、Hashtable集合
底层是哈希表数据结构,是线程同步的。不可以存储null键,null值。
/*
 * Hashtable和HashMap的区别?
 * A:Hashtable线程安全,效率低;不允许null键和值。
 * B:HashMap线程不安全,效率高;允许null键和值。
 */
public class HashtableDemo {
public static void main(String[] args) {
// HashMap<String, String> hm = new HashMap<String, String>();
// hm.put("hello", null);
// hm.put(null, "world");
// hm.put(null, null);
// System.out.println(hm);


Hashtable<String, String> ht = new Hashtable<String, String>();
// ht.put("hello", null);
// ht.put(null, "world");
// ht.put(null, null);
System.out.println(ht);
}
}




十一、Map.Entry 嵌套类
public static interface Map.Entry<K,V>映射项(键-值对)。Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。
0 0
原创粉丝点击