day_20 Map
hashSet
- 散列表 : 可以理解为数组保存元素是个链表
- 散列表中保存的是键值对(K和V)
- hashCode : hash算法,是把不定长的数据改变为定长的数据,是一种安全的加密算法,但不保证唯一
- 同一个对象生成多次hash值,那么值一定是相同的,
- 不同对象也有可能生成相同的hash值
- 添加过程 :
- 1 先调用添加的K,调用hashCode生成hash值
- 2 根据hash值计算数组下标
- 3 判断数组中该下标对应的位置上是否有元素
- 3.1 如果没有保存数据,就把该对象放到对应的下标中
- 3.2 如果保存了数据,此时调用添加的K的equals方法,和数组中该下标对应的所有数据的key进行比较
- 3.3 如果和数组下标对应的链表中 的数据 都不相等,就把该数据添加到对应的链表中
- 3.4 如果和链表中的数据一致了,则key不添加,把value值替换(用新的替换原来的)
- 4 java1.8新改动,如果该链表中,节点个数大于7,则该链表被转换为红黑树
- 在java把 没有散列表这个说法,只是把散列表封装为了HashMap和HashTable,并且HashTable已经过时
- 并且 HashMap的默认容量为 16
- HashSet 底层就是一个HashMap,并且只是Map的key部分,没有value
demo1
public class Collection_01_HashSet {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.add("xx");
set.add("xx");
set.add("xxx1");
set.add("xx2");
set.add("xx3");
System.out.println(set.size());
}
}
demo2
public class Collection_02_HashSet {
public static void main(String[] args) {
User user1 = new User(17, "张三");
User user2 = new User(15, "张三");
Set<User> users = new HashSet<User>();
users.add(user1);
users.add(user2);
System.out.println(users.size());
for (User user : users) {
// 结果是17张三,说明是添加不是替换
System.out.println(user);
}
}
}
//List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>();
class User {
private int age;
private String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
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;
User other = (User) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public User(int age, String name) {
super();
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]";
}
}
Map
Map : 无序 , key不可重复,value值可重复
Map和Collection不一样,但是操作基本上是一样的
集合保存单个对象,而map保存键值对映射关系
常用方法 :
put(K,V) : 添加数据
remove(K) : 删除数据
clear() : 清空
size() : 个数
isEmpty() : 判断是否为空
get(K) : 根据Key获取value
values() : 获取所有的value,返回集合
containsKey(K) : 判断是否包含某个key
containsValue(V) : 判断是否包含某个value
Set keySet() : 获取map中所有的key,返回set
Set entrySet() : 获取map中的键值对,返回set
public class Map_03_HashMap {
public static void main(String[] args) {
//创建map
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("a", 2);
map.put("A", 21);
map.put("'A'", 22);
map.put("65", 122);
// 个数 1
System.out.println(map.size());
// 根据key获取value , 2 因为key重复,value替换
System.out.println(map.get("a"));
// 是否包含某个key
System.out.println(map.containsKey("65"));
// 是否包含某个value
System.out.println(map.containsValue(2));
// 根据key删除该映射关系(K和V都删除,在链表中把该节点删除)
map.remove("a");
System.out.println(map.size());
// map不能直接遍历
// 获取所有的value
Collection values = map.values();
for (Object object : values) {
System.out.println(object);
}
// 获取所有的key
Set<String> sets = map.keySet();
for (String key : sets) {
System.out.println(key+":"+map.get(key));
}
// 将map转换为set,并把key和value封装到了entry类对象中,然后把entry类对象保存到set中即可
Set<Entry<String, Integer>> entries = map.entrySet();
for (Entry<String, Integer> entry : entries) {
// A=21
System.out.println(entry);
// getKey 是获取key,getValue 是获取value
System.out.println(entry.getKey()+"->"+entry.getValue());
}
}
}
Properties
- Properties : key和value强制要求必须是字符串
public class Map_04_Properties {
public static void main(String[] args) {
Properties p = new Properties();
// 添加数据
p.setProperty("driver", "mysql");
p.setProperty("username", "root");
// 获取数据
System.out.println(p.getProperty("driver"));
System.out.println(p.getProperty("username"));
// 不存在的key 得到null
System.out.println(p.getProperty("qweqw"));
// 有个方法重载,第二个参数为默认值,假如根据key找不到数据的时候,返回该默认值,而不是null
// 并不会把该键值对添加进去
System.out.println(p.getProperty("qweqw","默认值"));
}
}
TreeMap
- TreeMap : 保存的元素可以按照一定的规则进行排序
- 排序 :
- 1 要添加的元素 实现了Comparable接口
- 2 编写比较器类,实现Comparator接口
- treeMap 在添加的时候 会自动调用key对象的compareTo方法,是用key进行比较,而不是value
public class Map_05_TreeMap {
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<Integer, String>(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
map.put(1, "a");
map.put(2, "a");
map.put(12, "a");
map.put(11, "a");
Set set = map.entrySet();
for (Object object : set) {
System.out.println(object);
}
}
}
MapToList
- Map转换为List存储,并且以value进行排序
- 因为map没有办法以value排序,因为treeMap中只是按照key排序的,所以想要以value排序,需要转换为list
public class Map_06_MapToList {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("bbb", 2);
map.put("bcd", 1);
map.put("a1", 12);
// 把K和V封装到entry中,然后保存到set中
Set<Entry<String, Integer>> set = map.entrySet();
// set转换为list
List<Entry<String, Integer>> list = new ArrayList<Map.Entry<String,Integer>>(set);
// 更改排序
Collections.sort(list, new Comparator<Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
// 按照value值进行比较
return o1.getValue() - o2.getValue();
}
});
System.out.println(list);
}
}