1 Map
Map的常用子类:
——HashTable:内部结构是哈希表,是同步的。不允许null作为键或值。无序。
——Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
——HashMap:内部结构是哈希表,不是同步的 。允许null作为键或值。无序。
——TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。无序。
PS:HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。
1.1 Map:一次添加一对元素(即键值对——键:值),而Collection是一次添加一个元素。Map集合也称为双列集合,Collection集合称为单列集合。
1.2 Map保证元素唯一的方法:就是保证键的唯一性。就算同一个键对应两个不同的值,也算作重复元素。因为Map是通过键来索取值的。
1.2 Map常用方法
增——添加
value put(key,value);如果有这个key的话,就返回key关联的值,然后用新的键值把它替代掉,如果没有就返回nul,然后加入新键值
删——删除
void clear();清空map集合;
value remove(Object key);删除指定的key对应的键值对,并提取该值。
判断
boolean containsKey(key);判断是否含有指定key
boolean containsValue(value);判断是否含有指定的值;
boolean isEmpty();判断集合是否为空
查——获取
value get(key);根据指定的 键获取值,如果没有该值就返回null。可以通过返回null来判断是否包含指定键。
int size();获取键值对个数。
Collection value();获取该集合的值,作为Collection集合返回。
Set keySet();返回此集合中的键,作为Set集合
Set entrySet();返回此集合中的映射关系,作为Set集合
package demo;
import java.util.HashMap;
import java.util.Map;
public class Day18 {
public static void main(String[] args){
Map m = new HashMap();
System.out.println(m.put("male", "zhangsan"));
System.out.println(m.put("female","lisi"));
System.out.println(m.put("male","lisi"));
System.out.println(m.put("male","wangwu"));
System.out.println(m);
m.put(8, "八");
m.put(9, "九");
System.out.println(m.remove("male"));
System.out.println(m.containsKey(8));
System.out.println(m.containsValue("zhangsan"));
System.out.println(m.get("male"));
}
}
但是HashMap没有根据值获取键的方法,因为一个值可能有几个键。
1.3 Map的取出
Map没有迭代器,所以如果要遍历它,要用以下三种方法:
①需要先用keySet把键取出来,并用Set存储,再遍历Set集合,途中通过get(key)方法将每个键对应的值取出。
②使用entrySet()方法将map集合转成set集合(把映射关系(Map.Entry<>)存入Set),再通过迭代器取出。
Map.Entry<>是一个Map的一个内部接口,存储一对键值,即映射关系。这样,Set里的每个元素都是Map.Entry的一个实例对象。用getKey()和getValue()可得到键和值。同时也有setKey() setValue()
③直接用value()方法将值返回到一个Collection的子类集合中,然后遍历。
public class Day18{
public static void main(String[] args){
Map m = new HashMap();
m.put("zhangsan", 12);
m.put("lisi", 13);
m.put("wangwu", 15);
m.put("zhaoliu", 15);
System.out.println(m);
Set s = m.keySet();
System.out.println(s);
Iterator i = s.iterator();
while(i.hasNext()){
String str = (String) i.next();
// System.out.println(str);
int x = (Integer) m.get(str);
System.out.println(x);}
System.out.println("------------");
Set s1 = m.entrySet();
System.out.println(s1);
Iterator i1 = s1.iterator();
while(i1.hasNext()){
// System.out.println(i1.next().getClass());
// String me = (String) i1.next();
// System.out.println(me);
Map.Entry me = (Map.Entry)i1.next();
System.out.println(me.getKey()+"=="+me.getValue());
}
System.out.println("------------");
Collection coll = m.values();
Iterator i2 = coll.iterator();
while(i2.hasNext()){
System.out.println(i2.next());
}
}
}<span style="color:#ff0000;font-weight: bold;">
</span>
{lisi=13, zhaoliu=15, zhangsan=12, wangwu=15}
[lisi, zhaoliu, zhangsan, wangwu]
13
15
12
15
------------
[lisi=13, zhaoliu=15, zhangsan=12, wangwu=15]
lisi==13
zhaoliu==15
zhangsan==12
wangwu==15
------------
13
15
12
15
1.4 自定义HashMap排序
HashMap是按照HashCode和equals来排序而不是按照输入顺序。往往不是我们想要的排序方式。这时可以覆盖它的HashCode和equals,相当于创建了自己定义的“相同键判断方式”和“排序方式”了。
class Student{
private String name;
private int age;
Student(String name,int age){
this.name=name;
this.age=age;
}
void setName(String name){
this.name=name;
}
String getName(){
return name;
}
void setAge(int age){
this.age=age;
}
int getAge(){
return age;
}
public int hashCode(){
final int prime = 31;
int result=1;
result=prime*result+age;
result=prime*result+((name==null)?0:name.hashCode());
return result;
}
public boolean equals(Object obj){
if(this==obj)
return true;
if(obj==null)
return false;
if(getClass()!=obj.getClass())
return false;
Student s = (Student)obj;
if(age!=s.age){
return false;
}
if(name==null){
if(s.name!=null)
return false;
}else if (!name.equals(s.name))
return false;
return true;
}
}
public class Day18{
public static void main(String[] args){
HashMap<Student,String> hm = new HashMap<Student,String>();
hm.put(new Student("zhangsan",10),"beijing");
hm.put(new Student("lisi",13),"shanghai");
hm.put(new Student("wangwu",11),"guagnzhou");
hm.put(new Student("zhaoliu",14),"shenzhen");
hm.put(new Student("liuqi",12),"chegndu");
hm.put(new Student("zhaoliu",14),"shenzhen");
hm.put(new Student("zhaoliu",14),"nanjing");
Iterator<Student> i = hm.keySet().iterator();
while(i.hasNext()){
Student key = i.next();
String city = hm.get(key);
System.out.println(key.getName()+"...."+key.getAge()+"..."+city);
}
}
}
zhaoliu....14...nanjing
lisi....13...shanghai
liuqi....12...chegndu
zhangsan....10...beijing
wangwu....11...guagnzhou
PS:当键相同,后加入的元素会覆盖之前的元素。
1.5 LinkedHashMap
如果希望输入的键值对集合按照跟原来存入的顺序一致,就使用LInkedHashMap。
public class Day18{
public static void main(String[] args){
LinkedHashMap<String,String> lhm = new LinkedHashMap<String,String>();
lhm.put("zhangsan", "male");
lhm.put("lisi", "male");
lhm.put("wangwu", "female");
lhm.put("zhaoliu", "male");
lhm.put("liuqi", "female");
System.out.println(lhm);
Set<String> s = lhm.keySet();
Iterator i = s.iterator();
while(i.hasNext()){
System.out.println(i.next().hashCode());
}
}
}
{zhangsan=male, lisi=male, wangwu=female, zhaoliu=male, liuqi=female}
-1432604556
3322003
-795136991
-323273412
102984368
虽然LinkedHashMap能以输以顺序排序,但是它并没有在键的HashCode上做处理。
2 Collections工具
Collections:是集合框架的工具类,专门用于操作集合,里面的方法都是静态的。为集合提供了方便的方法。比如:要不考虑唯一性地存放一组对象,要用List接口,但是想要对该集合做排序的话,又不能用Tree的比较器。这是就可以用Collections里的sort()方法。不能给Set排序
2.1 排序
<T extends Comparable<? super T>> sort(List<> list);根据元素的自然顺序对指定列表按升序进行排序。
sort方法可以传入比较器sort(List<T> list, Comparator<? super T comp>
public class Day19 {
public static void main(String[] args){
sortDemo();
}
public static void sortDemo(){
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("bbb");
list.add("ddea");
list.add("bdfd");
list.add("bb");
System.out.println(list);
// Collections.sort(list);//默认是自然顺序
// System.out.println(list);
Collections.sort(list,new StrLenCom());
System.out.println(list);
}
}
class StrLenCom implements Comparator<String>{
public int compare(String s1, String s2){
if(s1.length()>s2.length())
? return 1;
if (s2.length()<s2.length())
return -1;
return s1.compareTo(s2);
// return 0;
}
}
Object Collections.Max(List list);求集合只能个自然排序的最大值
Object Collections.Max(List list, Comparator comp);求集合中的最大元素
2.3 二分法查找
二分法查找必须使元素具备可比性(即元素extends Comparable)或者方法里输入了比较器(即xxx implements Comparator)
<T> int Collections.binarySearch(List<? extend Comparable<? super T>> list, T key)
<T> int Collections.binarySearch(List<? extend T> list, T key, Comparator<? super T>)
2.4 替换
Collections.fill(List<? super T> list,Object obj);将集合中所有元素替换成指定元素
Collections.replacaAll(List<T> list,T oldVal, T newVal);j将集合中所有old元素替换成new元素
2.5 翻转
Collections.reverse(List<?> list)翻转指定列表中元素的顺序
2.6 洗牌
Collections.shuffle(List<T> list);将指定集合中的元素洗牌。
2.7 同步
因为集合框架中常用的集合类都是不同步的,一旦被多线程运用,就很容易出现安全问题。
比如添加元素,一次只能一个线程添加,否则会混乱。
Collection Collections.synchronizedCollection(Colleciton c);返回同步的Collection集合。
synchronizedList
synchronizedSet
...
3 Arrays
Arrays:用于操作数组的工具类
里面都是静态方法。
Arrays.asList():将数组变成List集合
把数组变成List集合的好处:可以使用集合的思想和方法来操作 数组中的元素。
class Day19{
public static void main(String[] args){
int[] i = {1,2,3,4,2,1};
String[] s = {"xxx","dfdf","kkk"};
List<String> l = Arrays.asList(s);
System.out.println(l);
System.out.println(l.contains("xxx"));
}
}
但是通过asList得来的集合不可以使用集合的增删方法。因为数组的长度是固定的。
可以使用
contains
get
indexOf
subList
...都可以
如果增删了,会发生不支持操作异常
class Day19{
public static void main(String[] args){
int[] i = {1,2,3,4,2,1};
String[] s = {"xxx","dfdf","kkk"};
List<String> l = Arrays.asList(s);
System.out.println(l);
System.out.println(l.contains("xxx"));
int[] nums = {1,2,4,3};
// List<Integer> l1 = Arrays.asList(nums);//cannot convert from List<int[]> to List<Integer>
List<int[]> l1 = Arrays.asList(nums);
System.out.println(l1);
Integer[] nums1 = {1,2,4,3};
List<Integer> l2 = Arrays.asList(nums1);
System.out.println(l2);
}
}
[xxx, dfdf, kkk]
true
[[I@659e0bfd]
[1, 2, 4, 3]
注意:如果是数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
如果数组中的元素都是基本数据类型,那么会将数组本体作为集合中的元素导入。
因为int[]只能作为"int[]"类型对象来装入。