黑马程序员-----集合 泛型
来源:互联网 发布:listview 优化的原理 编辑:程序博客网 时间:2024/06/11 08:45
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
泛型
定义:泛型:jdk1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制
好处:
1,将运行时期出现问题classcastexception,转移到了编译时期,方便于程序员解决问题,让运行事情问题减少,安全。
2,避免了强制转换麻烦
格式:
通过<>来定义要操作的引用数据类型
在集合框架中,只要见到<>就要定义泛型,其实<>就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
范例:
- public class GenericDemo3 {
- public static void main(String[] args) {
- Utils<Worker> u=new Utils<Worker>();
- u.setObject(new Worker());
- Worker w=u.getObject();
- /*Tool t=new Tool();
- t.setObject(new Worker());
- Worker w=(Worker)t.getObject();
- */
- }
- }
- class Worker
- {
- }
- class Student3
- {
- }
- //泛型前做法
- //什么时候定义泛型类?
- //当类中要操作的引用数据类型不确定的时候,早期定义object来完成扩展
- //现在定义泛型来完成扩展
- class Tool
- { private Object obj;
- public void setObject(Object obj)
- {
- this.obj=obj;
- }
- public Object getObject()
- {
- return obj;
- }
- }
- //泛型类。
- class Utils<QQ>
- {
- private QQ q;
- public void setObject(QQ q)
- {
- this.q=q;
- }
- public QQ getObject()
- {
- return q;
- }
- }
- /**
- class Tool
- { private worker w;
- public void setWorker(worker w)
- {
- this.w=w;
- }
- public worker getWorker()
- {
- return w;
- }
- }
- */
特殊之处:静态方法不可以访问类上定义的泛型,如果静态方法操作的 引用数据类型不确定,可以将泛型定义在方法上
泛型定在接口上的范例:
- public class genericDemo5 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- InterImpl<Integer> i=new InterImpl<Integer>();
- // InterImpl i=new InterImpl();
- i.show(4);
- }
- }
- class InterImpl<T> implements Inter<T>//泛型定义在接口上
- {
- public void show(T t)
- {
- System.out.println("show:"+t);
- }
- }
- /*class InterImpl implements Inter<String>
- {public void show(String t)
- {
- System.out.println("show:"+t);
- }
- }
- */
- interface Inter<T>
- {
- void show(T t);
- }
? extends E :可以接受E类型或者E的子类型,上限
? super E:可以接受E类型或E的父类型,下限。
- import java.util.*;
- class generademo6 {
- public static void main(String[] args)
- {
- /* ArrayList<String> a1=new ArrayList<String>();
- a1.add("abc1");
- a1.add("abc2");
- a1.add("abc3");
- ArrayList<Integer> a11=new ArrayList<Integer>();
- a11.add(4);//有自动装箱。
- a11.add(2);
- a11.add(5);
- printColl(a1);
- printColl(a11);*/
- ArrayList<Person> a1=new ArrayList<Person>();
- a1.add(new Person("abc1"));
- a1.add(new Person("abc2"));
- //printColl(a1);
- ArrayList<student11> a11=new ArrayList<student11>();
- a1.add(new student11("abc1"));
- a1.add(new student11("abc2"));
- printColl1(a11);//Arraylist<Person>a1=new Arraylist<Student>();是不允许的。error。两边一致
- }
- public static void printColl1(ArrayList<? extends Person/*泛型限定*/> a1)
- {
- Iterator<? extends Person> it=a1.iterator();
- while(it.hasNext())
- {
- System.out.println(it.next().getName());
- }
- }
- /*public static void printColl(ArrayList<?String>a1) //ArrayList<String>a1=new ArrayList<Integer>();不允许的。
- {
- Iterator<String? > it=a1.iterator();
- while(it.hasNext())
- {
- System.out.println(it.next());
- // System.out.println(it.next().length());//这不不能使用具体方法。
- }
- }*/
- }
- class Person
- {
- private String name;
- Person(String name)
- {
- this.name=name;
- }
- public String getName()
- {
- return name;
- }
- }
- class student11 extends Person
- {
- student11(String name)
- {
- super(name);
- }
- }
- class student11 implements Comparable<Person>//<? super e>
- {
- public int compareTo(Person s)
- {
- this.getName();
- }
- }
- class comp implements Comparator<Person>
- {
- public int compare(Person s1,Person s2)
- {
- return s1.getName().compareTo(s2.getName());
- }
- }
- TreeSet<student11> ts=new TreeSet<student11>(new comp());
- ts.add(new student11("abc11"));
Comparable 接口强行对实现它的每个类的对象进行整体排序,这种排序被称为自然排序。
Comparable只有comparableTo()
TreeSet内集合要具有比较性。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Map集合
Map
|-----Hashtable此类实现一个哈希表,该哈希表将键映射到相应的值,任何非null对象都可以用作键或值。
用作键的对象必须实现hashCode方法和equals方法。底层是哈希表数据结构,不可以存入null键null值,jdk1.0 效率低。该集合是线程同步的
|-----HashMap:基于哈希表的map接口的实现,并允许使用null键,null值。底层是哈希表数据结构,jdk1.2 效率高。该集合是非同步的。
|-----TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序
定义:public interface Map<K,V>将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值,collection单例集合,
Map集合:该集合存储键值对,一对一对往里存,而且保证键的唯一性。双列集合。
方法:
1,添加
put(k key,v value)将指定的值与此映射中的指定键关联
putAll(Map<? extends k,? extends v> m)从指定映射中将所有映射关系复制到此映射中
2,删除
void clear();从此映射中移除所有映射关系。即清空
value remove(Object key);如果存在一个键的映射关系,则将其从此映射中移除,删除指定键
3,判断
boolean containsKey(object key);如果此映射包含指定键的映射关系,则返回true, 是否包含key.
boolean containsValue(object value);如果此映射将一个或多个键映射到指定值,则返回true。是否包含value.
boolean isEmpty();如果此映射未包含键值映射关系,则返回true。
4,获取
value get(Object key)返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null
int size();返回此映射中的键值映射关系数。
Collection values();返回此映射中包含的值的collection视图。获取map集合中的所有的值。
entrySet();返回此映射中包含的映射关系的set视图。
keySet();返回此映射中包含的键的set视图。
5,想要获取map中的所有元素:
原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。
Map集合存储和Collection的区别:
Collection一次存一个元素;Map一次存一对元素。
Collection是单列集合;Map是双列集合。
Map中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。
- import java.util.*;
- public class MapDemo {
- public static void main(String[] args) {
- Map<String,String>map=new HashMap<String,String>();
- //添加元素,添加元素如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put
- //方法会返回被覆盖的值。
- map.put("01","zhangs");
- map.put("02", "jav12");
- map.put("03","jv23");
- System.out.print("cont"+map.containsKey("023"));
- System.out.println("remove"+map.remove("02"));
- System.out.println("get:"+map.get("023"));
- map.put("04", null);
- System.out.println("get:"+map.get("04"));
- //可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断
- //获取map集合中所有的值
- Collection<String> coll=map.values();
- System.out.println(coll);
- System.out.println(map);
取出map集合中所有元素的方式一:keySet()方法。
可以将map集合中的键都取出存放到set集合中。对set集合进行迭代。迭代完成,再通过get方法对获取到的键进行值的获取。
- Set keySet = map.keySet();
- Iterator it = keySet.iterator();
- while(it.hasNext()) {
- Object key = it.next();
- Object value = map.get(key);
- System.out.println(key+":"+value);
- }
set<Map.Entry<k,v>>entryset:将map集合中的映射关系存入到了set集合中,而这个集合的数据类型就是:Map.Entry
- Set entrySet = map.entrySet();
- Iterator it = entrySet.iterator();
- while(it.hasNext()) {
- Map.Entry me = (Map.Entry)it.next();
- System.out.println(me.getKey()+"::::"+me.getValue());
- }
- interface Map
- { public static interface Entry
- {
- public abstract Object getKey();
- public abstract Object getValue();
- }
- }
- class HashMap implements Map
- {
- class Hash implements Map.Entry
- {
- public Object getKey();
- public Object getValue();
- }
- }
- import java.util.*;
- public class mapdemo2 {
- public static void main(String[] args) {
- Map<String,String> map=new HashMap<String,String>();
- map.put("01","zhangs");
- map.put("02", "jav12");
- map.put("03","jv23");
- //将map集合中的映射关系取出,存入到set集合中,
- Set<Map.Entry<String, String>>entrySet=map.entrySet();
- Iterator <Map.Entry<String, String>>it1=entrySet.iterator();
- while(it1.hasNext())
- {
- Map.Entry<String, String>me=it1.next();
- String key=me.getKey();
- String value=me.getValue();
- System.out.print(key+":::"+value);
- }
- //先获取map集合的所有键的set集合,keyset();
- Set<String> keyset=map.keySet();
- //有了set集合,就可以获取其迭代器
- Iterator<String> it=keyset.iterator();
- while(it.hasNext())
- {
- String key=it.next();
- //有了键可以通过map集合的get方法获取其键对应的值
- String value=map.get(key);
- System.out.println("key:"+key+"value"+value);
- }
- }
- }
范例:map与映射有关,因为map就是键值对的映射
范例:
- import java.util.*;
- public class mapdemo31 {
- public static void demo()
- {
- HashMap<String,List<sstudent>>czbk=new HashMap<String,List<sstudent>>();
- List<sstudent> reyu=new ArrayList<sstudent>();
- List<sstudent> jiuye=new ArrayList<sstudent>();
- czbk.put("yureban", reyu);
- czbk.put("jiuyeban", jiuye);
- reyu.add(new sstudent("01","zhangshan"));
- reyu.add(new sstudent("02","zhangshan1"));
- jiuye.add(new sstudent("01","zhangshan2"));
- jiuye.add(new sstudent("02","zhangshan3"));
- //遍历czbk集合,获取所有的教室
- Iterator<String>it= czbk.keySet().iterator();
- while(it.hasNext())
- {
- String roomName=it.next();
- List<sstudent> room=czbk.get(roomName);
- System.out.println(roomName);
- getInfos(room);
- }
- }
- public static void getInfos(List<sstudent> list)
- {
- Iterator<sstudent>it=list.iterator();
- while(it.hasNext())
- {
- sstudent s=it.next();
- System.out.println(s);
- }
- }
- public static void main(String[] args) {
- demo();
- /** HashMap<String,HashMap<String,String>>czbk=new HashMap<String,HashMap<String,String>>();
- HashMap<String,String> yure=new HashMap<String,String>();
- HashMap<String,String> jiuye=new HashMap<String,String>();
- jiuye.put("01","zhaoli");
- jiuye.put("02","sdfs");
- czbk.put("yureban", yure);
- czbk.put("jiuyeban", jiuye);
- yure.put("01","zhaoli");
- yure.put("02","sdfs");
- //遍历czbk集合,获取所有的教室
- Iterator<String>it= czbk.keySet().iterator();
- while(it.hasNext())
- {
- String roomName=it.next();
- HashMap<String,String> room=czbk.get(roomName);
- System.out.println(roomName);
- getStudentInfo(room);
- }
- */
- //getStudentInfo(jiuye);
- }
- public static void getStudentInfo(HashMap<String,String> roomMap)
- {Iterator<String>it=roomMap.keySet().iterator();
- while(it.hasNext())
- {
- String id=it.next();
- String name=roomMap.get(id);
- System.out.println(id+"::"+name);
- }
- }
- }
- class sstudent
- {
- private String id;
- private String name;
- sstudent(String id,String name)
- {
- this.id=id;
- this.name=name;
- }
- public String toString()
- {
- return id+"::"+name;
- }
- }
Arrays:
用于操作数组对象的工具类,里面都是静态方法。asList方法:将数组转换成list集合。
String[] arr = {"abc","kk","qq"};
List<String> list = Arrays.asList(arr);//将arr数组转成list集合。
将数组转换成集合,有什么好处呢?用aslist方法,将数组变成集合;
可以通过list集合中的方法来操作数组中的元素:isEmpty()、contains、indexOf、set;
注意(局限性):数组是固定长度,不可以使用集合对象增加或者删除等,会改变数组长度的功能方法。比如add、remove、clear。(会报不支持操作异常UnsupportedOperationException);
如果数组中存储的引用数据类型,直接作为集合的元素可以直接用集合方法操作。
如果数组中存储的是基本数据类型,asList会将数组实体作为集合元素存在。
集合变数组:用的是Collection接口中的方法:toArray();
如果给toArray传递的指定类型的数据长度小于了集合的size,那么toArray方法,会自定再创建一个该类型的数据,长度为集合的size。
如果传递的指定的类型的数组的长度大于了集合的size,那么toArray方法,就不会创建新数组,直接使用该数组即可,并将集合中的元素存储到数组中,其他为存储元素的位置默认值null。
所以,在传递指定类型数组时,最好的方式就是指定的长度和size相等的数组。
将集合变成数组后有什么好处?限定了对集合中的元素进行增删操作,只要获取这些元素即可。
- import java.util.*;
- public class arrayDemo {
- public static void main(String[] args) {
- //int arrp[]={2,4,5};
- //System.out.println(Arrays.toString(arrp));
- String[]arr={"we","wer","wet"};
- //把数组变成list集合有什么好处?
- // 可以使用集合的思想和方法来操作数组中的元素
- // 注意:将数组变成集合,不可以使用集合的增删方法
- // 因为数组的长度是固定
- // contains get indexof() sublist()
- // 如果增删,那么会发生unsupportedOperationException
- List<String>list=Arrays.asList(arr);
- System.out.println(list.contains("cc"));
- list.add("aa");//unsupportedOperationException 不支持操作异常
- System.out.println(list);
- // int[] num={2,3,4};
- Integer[] nums={3,4,4};
- List<Integer>li=Arrays.asList(nums);
- // List<int[]>li=Arrays.asList(num);
- // 如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素
- // 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
- System.out.println(li);
- }
- public static boolean myContains(String[]arr,String key)
- {
- for(int x=0;x<arr.length;x++)
- {
- if(arr[x].equals(key))
- return true;
- }
- return false;
- }
- }
Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性。
—————————————————————————————————————————————————————————————————————————
增强for循环:
foreach语句,foreach简化了迭代器。
格式: 增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器
for( 元素类型 变量名 : Collection集合 & 数组 ) {
…
- String [] arr = {"a", "b", "c"};//数组的静态定义方式,只试用于数组首次定义的时候
- for(String s : arr) {
- System.out.println(s);
- }
增强for循环和传统for循环的区别:
高级for循环在使用时,必须要明确被遍历的目标。这个目标,可以是Collection集合或者数组,如果遍历Collection集合,在遍历过程中还需要对元素进行操作,比如删除,需要使用迭代器
如果遍历数组,还需要对数组元素进行操作,建议用传统for循环因为可以定义角标通过角标操作元素。如果只为遍历获取,可以简化成高级for循环,它的出现为了简化书写。
增强for循环迭代:
原则上map集合是无法使用增强for循环来迭代的,因为增强for循环只能针对实现了Iterable接口的集合进行迭代;
Iterable是jdk5中新定义的接口,就一个方法iterator方法,只有实现了Iterable接口的类,才能保证一定有iterator方法,java有这样的限定是因为增强for循环内部还是用迭代器实现的,而实际上,我们可以通过某种方式来使用增强for循环。
- for(Object obj : map.entrySet()) {
- Map.Entry entry = (Entry) obj; // obj依次表示Entry
- System.out.println(entry.getKey() + "=" + entry.getValue());
- }
在迭代集合的过程中,不能对集合进行增删操作(会报并发访问异常);可以用迭代器的方法进行操作(子类listIterator:有增删的方法)。
在使用增强for循环时,不能对元素进行赋值;
——————————————————————————————————————————————————
JDK1.5出的几个新特性
1,可变参数
- public class paramMethodDemo {
- public static void main(String[] args) {
- }
- //可变参数,其实就是上一种数组参数的简写形式,不用每一次都动手的建立数组对象,只要将要操作的元素作为参数传递即可
- //隐试将这些参数封装成了数组。
- public static void show(String str,int... arr)
- {
- System.out.println(arr.length);
- }
- /*public static void show(int a,int b)
- {}
- public static void show(int a,int b,int c)
- {}*/
- }
和以前接收数组不一样的是:
以前定义数组类型,需要先创建一个数组对象,再将这个数组对象作为参数传递给函数。现在,直接将数组中的元素作为参数传递即可。底层其实是将这些元素进行数组的封装,而这个封装动作,是在底层完成的,被隐藏了。所以简化了用户的书写,少了调用者定义数组的动作。
如果在参数列表中使用了可变参数,可变参数必须定义在参数列表结尾(也就是必须是最后一个参数,否则编译会失败。)。
如果要获取多个int数的和呢?可以使用将多个int数封装到数组中,直接对数组求和即可。
2,静态导入
staticImport静态导入
静态导入:导入了类中的所有静态成员,简化静态成员的书写。
当类名重名时,需要指定具体的报名,
当方法重名时,指定具备所属的对象或者类。
- import static java.util.Collections.*; //导入了Collections类中的所有静态成员
- import java.util.*;
- import static java.util.Arrays.*;//导入的是arrays这个类中的所有的静态成员
- import java.lang.System.*;//导入了system类中所有静态成员。
- public class StaticImport {
- public static void main(String[] args) {
- int[]arr={3,4,5};
- sort(arr);//Arrays.sort(arr);
- int index=binarySearch(arr, 1);
- System.out.println(Arrays.toString(arr));
- System.out.println(index);
- }
- }
java中数据类型分为两种:基本数据类型 引用数据类型(对象)
基本---引用 Integer x = new Integer(x);
引用---基本 int num = x.intValue();
4,泛型通配符
可以解决当具体类型不确定的时候,这个通配符就是? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
5,泛型限定:
上限:?extends E:可以接收E类型或者E的子类型对象。
下限:?super E:可以接收E类型或者E的父类型对象。
- 黑马程序员---集合,泛型
- 黑马程序员-----集合 泛型
- 黑马程序员---集合框架<泛型>
- 黑马程序员----集合框架、泛型
- 黑马程序员-----泛型,Map集合
- 黑马程序员------------泛型,Map集合
- 黑马程序员-----泛型,Map集合
- 黑马程序员-----泛型,Map集合
- 黑马程序员-----泛型,Map集合
- 黑马程序员-- java集合类--Vector/泛型
- 黑马程序员 java集合—泛型
- 黑马程序员 课后日记--泛型-Map集合
- 41.黑马程序员-集合框架、泛型
- 黑马程序员_集合框架(泛型)
- 黑马程序员_泛型、Map集合
- 黑马程序员_java_集合框架_Collection_List_Set_Map_泛型
- 黑马程序员_java_集合框架_Collection_List_Set_泛型
- 黑马程序员_集合、可变参数、泛型
- Android Studio导入library project第三方类库
- view 与viewGroup的关系
- 归并排序的简单实现(c++ 版本)
- freescale spi driver
- 关于今晚的实验 自己做出来的 满满的成就感感觉自己棒棒哒
- 黑马程序员-----集合 泛型
- 60s经济学
- Android 自定义视图 onMeasure,MeasureSpec 思路详解
- MySQL教程
- 大数据技术——Storm
- 类是如何定义出来的
- 产品经理:不懂放权给用户,活该你叫“产品狗”
- iOS CoreData_基本表的增加
- 51单片机单串口同时实现AT指令和调试信息输出