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

黑马程序员_API_泛型&map集合

2014-05-16 12:09 246 查看
----------- android培训java培训、期待与您交流!----------

一、泛型
JDK1.5版本出现的新特性,安全机制。
泛型将运行时期的问题转移到了编译时期。
避免了强制转换的麻烦。
泛型技术是用于编译时期的技术。

泛型的体现:
<>  这就是用于定义类型参数的符号。
泛型可以简单的理解为,接收具体的元素类型。

对源码进行编译时,通过泛型进行类型的检查。
如果类型没有问题,则将源码编译成class文件。
注意,class文件中是不带有泛型信息的。这种情况称之为泛型擦除。

1、 泛型类,泛型方法,泛型接口什么时候用
泛型类:当类中操作的对象不确定时,可以在类中声明泛型。使用时传入具体类型即可。
泛型方法:当方法要操作的数据类型不确定时可以定义泛型,使用的时候传入具体的类型即可。如果是在静态方法上使用泛型,该泛型必须定义在方法上。
泛型接口:接口中的抽象方法中的参数类型不确定时,可以在接口上声明泛型,方法中可以使用声明后的泛型参数,
 具体类型由实现类指定。当实现类也不知道类型时,由实例化实现类时来明确具体类型

2、 泛型的通配符,以及泛型的限定的表现形式,和用法,以及什么时候用
? extends E: 存储元素对象的时候用,你定义的是E类型,我们可以存储E类型或者E的子类型的对象。
? super E:从容器中取出元素时使用,容器中有E类型对象,取出时可使用E类型接收,或者E的父类型接收。比如比较器。

3、 泛型限定的方法,比如TreeSet集合的构造函数。
添加元素一般用上限,取出元素一般用下限。
? extends E :接收E类型或者E的子类型。上限
? super E : 接收E类型或者E的父类型。下限

public class ComparatorByAge implements Comparator<Person> {

@Override
public int compare(Person p1, Person p2) {
int temp = p1.getAge() - p2.getAge();
return temp == 0 ? p1.getName().compareTo(p2.getName()) : temp;
}
}

public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByAge());

ts.add(new Person("zhangsan", 21));
ts.add(new Person("lisi", 24));
ts.add(new Person("zhangsan", 21));
printCollection(ts);

TreeSet<Student> ts2 = new TreeSet<Student>(new ComparatorByAge());
ts2.add(new Student("abc1", 21));
ts2.add(new Student("abc2", 24));
ts2.add(new Student("abc5", 21));
printCollection(ts);

}

public static void printCollection(Collection<? extends Person> coll) {
Iterator<? extends Person> it = coll.iterator();
while (it.hasNext()) {
Person p = it.next();
System.out.println(p.getName() + ":" + p.getAge());

}
}
}


4、 T和?的区别
T是声明了一个类型参数,接收一个具体的类型,用这个参数可以对具体的类型进行操作。?是未知,不能使用,只能标识。

二、Map集合
Map集合中存储的是一对儿元素。键和值。之间存在着对应关系。
必须要保证键的唯一性。

如果存储键相同,值会覆盖。

 获取Map中的所有键值对。

 Map取出所有元素的原理:将map先转成set,在使用迭代器。

只有list集合才具备增删改查。

最早的单列集合是Vector,双列集合是Hashtable

set集合底层实际是map

其他集合都具备的特点就是:凡事容器都具备自己的添加、删除、判断的功能。

set底层用的就是map集合,底层调用的都是map的方法。

Map.Entry内部接口,Entry是静态的
静态的内部类或者静态的接口本身就相当于一个外部类和接口,因为他是随着外部类的加载就加载了。

1、Map集合的特点以及常见子类的特点?
Hashtable:数据结构是哈希表,是同步的,不允许键和值为null
HashMap:数据结构是哈希表,是不同步的,运行键和值为null
TreeMap:数据结构是二叉树,是不同步的,可以对集合中的键进行排序。

2、Map集合和Collection集合的区别?
Collection存储是一个,Map存储元素是一对。
Collection一些集合元素可以重复,Map集合的键需要保证唯一性。重复键会覆盖。

3、取出元素的三种方式
第一种方式:
获取map集合中的键的集合。keySet();
Set<String> keySet = map.keySet();
第二种方式:
获取map集合中所有的键值关系集合。entrySet,键值关系的类型是 Map.Entry.
Set<Map.Entry<String, String>> entrySet = map.entrySet();
第三种方式:获取值的集合。values();

Collection<String> values = map.values();

public class Test {

public static void main(String[] args) {

/*
* "ert+yuiodf8g.hjkt"想要知道每个字母出现的次数。
* a(3)b(5)c(1)e(6).....
*
* 思路:
* 	发现字母和次数之间存在着对应关系,所以可以使用map集合。
*	发现要求的结果中abc等出现是有顺序的。所以可考虑使用TreeMap。
* 	map集中,存储的就是字母和对应的次数,字母作为键。map作为表。
*  将字符串中的每一个字母都去查表。如果该字母没查找对应的次数,就将该字母和1存储到表中。
*  如果查到次数,将次数加+1后,将该字母和次数存储到表中。
*
*/
String str = "erAt+yuAeioCrdCfe8g.hyjkt";
str = sortChar(str);
System.out.println(str);
}

public static String sortChar(String str){

//1,定义一个存储字母和次数的表。TreeMap.
Map<Character,Integer> map = new TreeMap<Character,Integer>();

//2,将字符串转成字符数组。
char[] chs = str.toCharArray();

//3,对数组进行遍历。
for(int x=0; x<chs.length; x++){

if(!isLetter(chs[x])){
continue;
}
//将遍历到的字符作为键。去查表。获取对应的次数。
Integer value = map.get(chs[x]);
int count = 0;
if(value!=null){
count = value;
}
count++;

//将字母和对应的次数存储到map集合中。
map.put(
9cf2
chs[x], count);

}

return mapToString(map);
}

/*
* 将map集合转成指定格式的字符串。键(值)键(值)....
*/
private static String mapToString(Map<Character, Integer> map) {

//元素很多,最终要变成字符串。
StringBuilder sb = new StringBuilder();

//遍历map。
Iterator<Map.Entry<Character, Integer>> it = map.entrySet().iterator();

while(it.hasNext()){

Map.Entry<Character, Integer> me = it.next();

Character key = me.getKey();
Integer value = me.getValue();

sb.append(key+"("+value+")");
}

return sb.toString();
}

/*
* 判断字符是否是字母。
*/
private static boolean isLetter(char c) {

return c>='a' && c<='z' || c>='A' && c<='Z';
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: