您的位置:首页 > 职场人生

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

2015-08-08 02:25 555 查看
------- <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 视图,其中的元素属于此类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  黑马程序员