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

----------- 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(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';
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值