1.Map集合
该集合存储键值对。一对一对往里存。而且要保证
键的唯一性。
1,添加。
put(K key, V value)
putAll(Map<? extends K,? extends V> m)
2,删除。
clear()
remove(Object key)
3,判断。
containsValue(Object value)
containsKey(Object key)
isEmpty()
4,获取。
get(Object key)
size()
values()
entrySet()
keySet()
Map
|--Hashtable:底层是哈希表数据结构,
不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
|--HashMap:底层是哈希表数据结构,
允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像。
其实大家,
Set底层就是使用了Map集合。
map.put()会返回这个键原来的的值。
map集合的两种取出方式:
1,Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。
所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。
2,Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,
而这个关系的数据类型就是:Map.Entry
Entry其实就是Map中的一个static内部接口。
为什么要定义在内部呢?
因为只有有了Map集合,有了键值对,才会有键值的映射关系。
关系属于Map集合中的一个内部事物。
而且该事物在直接访问Map集合中的元素。
<p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span style="background-color: inherit; font-family: 宋体;">练习:</span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span lang="EN-US" style="background-color: inherit;">"sdfgzxcvasdfxcvdf"</span><span style="background-color: inherit; font-family: 宋体;">获取该字符串中的字母出现的次数。</span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span lang="EN-US" style="background-color: inherit;"><span style="background-color: inherit;"> </span></span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span style="background-color: inherit; font-family: 宋体;">希望打印结果:</span><span lang="EN-US" style="background-color: inherit;">a(1)c(2).....</span></p>package nuddles.j2seDemo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
* @param args
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> map = new HashMap<String, String>();
map.put("11", "22");
System.out.println(map.put("11","33"));
// 返回原值“22”;
map.put("33", "44");
map.put("34", "44");
map.put("35", "44");
map.put("36", "44");
map.put("39", "44");
Set<String> set = map.keySet();
// 用keySet取出
for (String string : set) {
System.out.println(string+","+map.get(string));
}
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for(Map.Entry<String, String> mapEntry:entrySet){
// 用entrySet取出
System.out.println(mapEntry.getKey()+","+mapEntry.getValue());
}
}
}
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
1,描述学生。
2,定义map容器。将学生作为键,地址作为值。存入。
3,获取map集合中的元素。
import java.util.*;
class Student implements Comparable<Student>{
// 实现Comparable接口
private String name;
int age;
Student(String name, int age){
this.name = name;
this.age = age;
}
public int compareTo(Student s){
// 重写此方法
if (this.age==s.age) {
return this.name.compareTo(s.name);
}else {
return new Integer(this.age).compareTo(s.age);
}
}
public int hashCode(){
return this.name.hashCode()+this.age;
}
public boolean equals(Object obj){
if (! (obj instanceof Student)) {
throw new ClassCastException();
}
Student ss = (Student)obj;
return this.name.equals(ss.name)&&this.age == ss.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+":"+age;
}
}
public class MapTest1 {
public static void main(String[] args) {
Map<Student,String> map = new HashMap<Student,String>();
map.put(new Student("nuddles01",23),"jiangxi");
map.put(new Student("nuddles02",23),"jiangxi");
map.put(new Student("nuddles03",23),"jiangxi");
map.put(new Student("nuddles01",23),"jiangxi");
sop(map);
Set<Map.Entry<Student,String>> me = map.entrySet();
for(Map.Entry<Student,String> e:me){
// 高级For循环取出
Student stu = e.getKey();
String adr = e.getValue();
sop(stu.toString()+","+adr);
}
Set<Student> set = map.keySet();
for(Student stu:set){
String adr = map.get(stu);
sop(stu.toString()+","+adr);
}
/*Set<Map.Entry<Student,String>> me = map.entrySet();
Iterator<Map.Entry<Student,String>> it = me.iterator();
while (it.hasNext()) {
Map.Entry<Student,String> e = it.next();
Student stu = e.getKey();
String adr = e.getValue();
sop(stu.toString()+","+adr);
}
Set<Student> keyset = map.keySet();*/
/*Iterator<Student> itr = keyset.iterator();
while (itr.hasNext()) {
Student stu = itr.next();
sop(stu.toString()+","+map.get(stu));
}*/
}
public static void sop(Object obj){
System.out.println(obj);
}
}
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
希望打印结果:a(1)c(2).....
/*
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
希望打印结果:a(1)c(2).....
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。
什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。
思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3,遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。
4,将map集合中的数据变成指定的字符串形式返回。
*/
package nuddles.j2seDemo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String string = "sdfgzxcvasdfxcvdf";
charCount(string);
}
public static void charCount(String string){
Map<Character,Integer> map = new HashMap<Character, Integer>();
int count;
char[] cha = string.toCharArray();
for (char c : cha) {
// if (!(c>='a'&&c<='z'|| c>='A'&&c<='Z')) {
if (!(new Character(c).toString().matches("[a-zA-Z]"))) {
// 用正则表达式来判断是不是字母
continue;
}
Integer value = map.get(c);
if (value != null ) {
// 如果map中已经有这个字母,则相应值加1
count = value;
count++;
map.put(c, count);
}else {
// 没有则初始化为1
map.put(c, 1);
}
}
Set<Character> set = map.keySet();
StringBuilder sb = new StringBuilder();
// 用StringBuilder来汇总
for (char c : set) {
sb.append(c+"("+map.get(c)+")");
}
System.out.println(sb.toString());
}
}
f(3)v(2)g(1)d(3)s(2)c(2)a(1)z(1)x(2)
2.集合框架的工具类。
Collections:集合框架的工具类。里面定义的都是静态方法。
Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
Collections是集合框架中的一个工具类。该类中的方法都是静态的
提供的方法中有可以对list集合进行排序,二分查找等方法。
通常常用的集合都是线程不安全的。因为要提高效率。
如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
Collections.sort(list);//list集合进行元素的自然顺序排序。
Collections.sort(list,new ComparatorByLen());//按指定的比较器方法排序。
class ComparatorByLen implements Comparator<String>{
public int compare(String s1,String s2)
{ int temp = s1.length()-s2.length();
return temp==0
s1.compareTo(s2):temp;
}
}
Collections.max(list);//返回list中字典顺序最大的元素。
int index = Collections.binarySearch(list,"zz");//二分查找,返回角标。必须是有序的
Collections.fill();//可以将list集合中的所有元素替换成指定元素。
Collections.repalceAll(list,"要被替换的","替换的值");//可以将list集合中的指定元素替换成指定元素。
Collections.reverse(); 反转
Collections.reverseOrder(参数是比较器);//逆向反转排序。倒序。。
Collections.shuffle(list);//随机对list中的元素进行位置的置换。
将非同步集合转成同步集合的方法:
Collections中的 XXX synchronizedXXX(XXX);
List synchronizedList(list);
Map synchronizedMap(map) ;
原理:定义一个类,将集合所有的方法加同一把锁后返回。
import java.util.*;
import static java.util.Collections.*;
class CollectionsDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("zzzz");
list.add("kkkl");
list.add("zzz");
sop(list);
sort(list,new StrLength());
sop(list);
sort(list,reverseOrder(new StrLength()));
sop(list);
sop(max(list,new StrLength()));
sop(binarySearch(list,"zzz"));
shuffle(list);
sop(list);
fill(list,"bbb");
sop(list);
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class StrLength implements Comparator<String>{
public int compare(String s1,String s2){
if (s1.length()>s2.length()) {
return 1;
}else if (s1.length()<s2.length()) {
return -1;
}else {
return s1.compareTo(s2);
}
}
}
Compiling CollectionsDemo.java.......
-----------OUTPUT-----------
[aaa, zzzz, kkkl, zzz]
[aaa, zzz, kkkl, zzzz]
[zzzz, kkkl, zzz, aaa]
zzzz
2
[aaa, zzzz, kkkl, zzz]
[bbb, bbb, bbb, bbb]
[Finished in 0.8s]
集合变数组。
Collection接口中的toArray方法。
1,指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。
长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。
而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
2,为什么要将集合变数组?
为了限定对元素的操作。不需要进行增删了。
4.Arrays:用于操作数组的工具类。
里面都是静态方法。
asList:将数组变成list集合
把数组变成list集合有什么好处?
可以使用集合的思想和方法来操作数组中的元素。
注意:将数组变成集合,不可以使用集合的增删方法。
因为数组的长度是固定。
contains。
get
indexOf()
subList();
如果你增删。那么会反生UnsupportedOperationException,
如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
如果数组中的元素都是基本数据类型,
那么会将该数组作为集合中的元素存在。
df
import java.util.*;
import static java.util.Arrays.*;
class ArraysDemo {
public static void main(String[] args) {
int[] arr = {3,4,24,5,6,3};
List al = asList(arr);
sop(al);
Integer[] arr2 = {3,4,24,5,6,3};
List al2 = asList(arr2);
sop(al2);
sop(al2.contains(3));
}
public static void sop(Object obj){
System.out.println(obj);
}
}
Compiling ArraysDemo.java.......
-----------OUTPUT-----------
[[I@1db9742]
[3, 4, 24, 5, 6, 3]
true
[Finished in 0.8s]
-----------OUTPUT-----------
[[I@1db9742]
[3, 4, 24, 5, 6, 3]
true
[Finished in 0.8s]
5.高级for循环
格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{
}
对集合进行遍历。
只能获取集合元素。但是不能对集合进行操作。
迭代器除了遍历,
还可以进行remove集合中元素的动作。
如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
传统for和高级for有什么区别呢?
高级for有一个局限性。必须有被遍历的目标。
建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。