集合框架

来源:互联网 发布:淘宝的软件靠谱么 编辑:程序博客网 时间:2024/06/11 09:53

集合框架

在没有学集合框架之前,我们存多个数据只会用数组,但是学了集合类后,我们存储多个数据就可以直接调用。

在总结集合笔记之前,我们先学泛型,以泛型进入集合会更好理解。

泛型:

一、泛型的含义:

1、广泛通用的类型。

2、代码模板中类型不确定,谁调用该段代码,谁指明类型是什么。

二、为什么要使用泛型?

1、存储任意类型的数据在集合中 ,但是取出来都是Object类型的,此时就得强转,使用泛型避免了数据类型转换的异常

2、约束存储到集合中的元素必须是相同的数据类型(相同的数据类型才能做比较,比如TreeSet)

3、设计一个点(Point),来封装坐标位置,要求坐标位置支持引用数据类型String类型.Integer类型/Double类型)。

三、泛型的使用:

1、保证前后类型相同

2、泛型与子类继承的限制(在泛型中不能用父类来接受子类)

3、泛型类中的泛型只能适用于非静态方法

4、型类中的泛型应该适用于整个类中多个方法,有时候只对某一个方法设置泛型即可。

Demo:

public class GeneralDemo2 { public static void main(String[] args) {System.out.println(MethodDemo.test("huairen"));Person1<String,Car<Integer>> p = new Person1<String,Car<Integer>>("张浩", new Car<Integer>(2));System.out.println(p.getTemp1()+p.getTemp2());} }//静态方法不能使用类上定义的泛型class MethodDemo<V>{public static <T> T test(T temp){return temp;}//错误/*public static void test2(V temp){System.out.println(temp);}*/public <T> T[] test3(T[] temp){return temp;}} class Person1<V,T>{private V temp1;private T temp2;public Person1(V temp1, T temp2) {this.temp1 = temp1;this.temp2 = temp2;}public V getTemp1() {return temp1;}public void setTemp1(V temp1) {this.temp1 = temp1;}public T getTemp2() {return temp2;}public void setTemp2(T temp2) {this.temp2 = temp2;}} class Car<V>{private V temp; public Car(V temp) {this.temp = temp;} public V getTemp() {return temp;} public void setTemp(V temp) {this.temp = temp;} @Overridepublic String toString() {return "此车"+temp+"轮胎";}}


四、通配符:

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知此时只能接受数据,不能往该集合中存储数据。

泛型的上限和下限:用来限定元素的类型必须是X类的子类或相同,  X的父类或相同。

Demo

public class GeneralDemo { public static void main(String[] args) {//1.泛型中不能使用基础数据类型,只能使用包装类//泛型中不能使用父类接收子类Point<Integer,String> p2 = new Point<Integer,String>(2,"北纬22度");System.out.println(p2);new Person().getPoint(p2);}}class Person{//extends相当于小于或等于//super相当于大于等于public void getPoint(Point<?extends Number,?super String> p){System.out.println("人在"+p);}}class Point<T,V>{private T x;private V y;public Point(T x, V y) {this.x = x;this.y = y;}public T getX() {return x;}public void setX(T x) {this.x = x;}public V getY() {return y;}public void setY(V y) {this.y = y;}public String toString() {return "("+x+","+y+")";}}


 

五、泛型数组:

Demo

public class GenericsDemo { public static void main(String[] args) {Integer[] a = {1,2,3,4,5};GenericsArrays ga = new GenericsArrays();ga.test(a);Integer[] b = ga.testReturn(a);for (int i = 0; i < b.length; i++) {System.out.println(b[i]);} }} class GenericsArrays{public<T> void test(T a[]) {for (int i = 0; i < a.length; i++) {System.out.println(a[i]);}System.out.println("-------");}public<T> T[]testReturn(T a[]){return a;}}


----------------------------------------------------------------

集合:

一、什么是集合?

集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口接口的实现对集合运算的算法(底层都对应着某一种数据结构的算法)

集合也就是一个动态的对象数组,可以不限制定义,不像数组那样有长度限制。


二、常用的框架接口规范:

1集合中存储的对象,称之为集合元素;

2、集合中只能存储任意类型的对象;

3、集合中只能存储对象,不能存储基本数据类型的值;

4、集合类中存储的对象,都存储的是对象的引用,而不是对象本身.


三、常用的集合类:

1Set():集合中的对象不按特定方式排序,不允许元素重复.

 2 List(列表):集合中的对象按照索引位置排序,允许元素重复.

3Map(映射):集合中每一个元素都包含一对keyvalue对象.不允许key对象重复,值对象可以重复


四、集合类的操作方法:

1增加:

A) boolean add(Object e) 将指定元素添加到此向量的末尾,等价于addElement方法。

B) void add(int index, Object element)  在此向量的指定位置插入指定的元素。

C) boolean addAll(Collection c) :c集合中的元素添加到当前集合对象中.

 

2删除:

A) Object remove(int index) :删除指定索引位置的元素,并返回删除之后的元素.

B) boolean remove(Object o):删除指定的元素.

boolean removeAll(Collection c):从此集合中移除包含在指定 集合c中的所有元素。

C) boolean retainAll(Collection c):在此集合中仅保留包含在指定 集合c中的元素,求两个集合的交集。

 3修改:

A) Object set(int index, Object element) :修改当前集合中指定索引位置的元素。返回被替换的旧的元素.

4查询:

A) int size()  :返回当前集合中存储几个元素.

B) boolean isEmpty():如果当前集合中不包含指定元素,是则返回true.

C) boolean contains():如果当前集合中包含指定元素,是则返回true.

D) Object  get(int index):查询指定索引位置的元素.

E) Object[] toArray():把集合对象转换为Object数组.

 

五、List

特点:1)可以重复放入元素,只会删除集合中最先找到的元素;

2)记录元素的先后添加顺序。

ArrayList

1、ArrayList类相当于vector类是一个Object数组,是Java集合框架出现之后用来取代Vector类的,二者底层原理都是基于数组的算法,一模一样。

2、区别:

A) Vector:  所有的方法都使用了synchronized修饰符.      线程安全但是性能较低.  适用于多线程环境.

B) ArrayList:所有的方法都没有使用synchronized修饰符.   线程不安全但是性能较高.

即使以后在多线程环境下,我们也不使用Vector:

ArrayList list = Collections.synchronizedList(new ArrayList(...));

LinkedList子类(一个链表操作类):

1定义:LinkedList类是双向链表,单向队列,双向队列,栈的实现类:

2LinkedList类实现单向队列和双向队列的接口,自身提高了栈操作的方法,链表操作的方法.

3、在LinkedList类中存在很多方法,但是功能都是相同的.LinkedList表示了多种数据结构的实现,每一种数据结构的操作名字不同。

4LinkedList擅长保存和删除操作。

Demo

public class LinkedListDemo {public static void main(String[] args) {//创建链表LinkedList<String> ld = new LinkedList<String>();ld.add("苹果1");ld.add("苹果2");ld.add("苹果3");ld.add("苹果4");ld.add("苹果5");System.out.println(ld);//在链表首尾添加ld.addFirst("苹果0");ld.addLast("苹果6");System.out.println(ld);//找到链表的头System.out.println(ld.element());System.out.println(ld.peek());System.out.println(ld.poll());System.out.println(ld);//按照先进先出的思想取出链表里的元素for(int i=0;i<6;i++){//注意这里不能写成 ld.size();因为ld.size()的值在随着链表里的元素被移除而变化System.out.println(ld.poll()+":"+i);}}//element:找到头;//peek:找到头;//poll:找到头并删除头;}


七、迭代器(Iterator):

1、迭代器对象:

    A) Iterator: 迭代器对象,只能从上往下迭代.

    B) boolean  hasNext(); 判断当前指针后是否有下一个元素

    C) Object    next():获取指针的下一个元素,并且移动指针.

    D) ListIterator:  Iterator接口的子接口,支持双向迭代,从上往下迭代,从下往上迭代.

 

Demo:

public class IteratorDemo { public static void main(String[] args) {List<Apple> a = new ArrayList<Apple>();a.add(new Apple("a1"));a.add(new Apple("a2"));a.add(new Apple("a3"));a.add(new Apple("a4"));a.add(new Apple("a5"));Iterator<Apple> it = a.iterator();while(it.hasNext()) {System.out.println(it.next()+",");}}}class Apple{private String name; public Apple(String name) {super();this.name = name;} @Overridepublic String toString() {return "Apple [name=" + name + "]";}}


八、Set类:

特点:1):不允许元素重复(采用散列存储);

      2):不会记录元素的先后添加顺序;

3)Set判断两个对象是否相等用equals,而不是使用==。也就是说两个对象equals比较返回trueSet集合是不会接受这个两个对象的。

Hashset类:

 1不保证元素的先后添加顺序.

  2、底层才有的是哈希表算法,查询效率极高.

  3判断两个对象是否相等的规则:                                               

 a):equals比较为true.

 b):hashCode值相同.

要求:要求存在在哈希中的对象元素都得覆盖equalshashCode方法.    

HashSet做等值查询效率高,TreeSet做范围查询效率高.

  Demo

public class TreeSetDemo1 {public static void main(String[] args) {HashSet<Dog> ts = new HashSet<Dog>();ts.add(new Dog("狗1", 6));ts.add(new Dog("狗2", 4));ts.add(new Dog("狗2", 4));ts.add(new Dog("狗2", 4));ts.add(new Dog("狗3", 2));ts.add(new Dog("狗4", 5));System.out.println(ts);}}class Dog{private String name;private int age;public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String toString() {return (this.name + ":" + this.age);}public boolean equals(Object obj){//首先判断是不是我们要判断的类型if(!(obj instanceof Dog)){return false;}//判断是不是不同名字,但是指向了同一个if(this == obj ){return true;}//判断是不同的对象,但是值确是一样Dog d = (Dog)obj;if(this.age == d.getAge()&&this.getName()==d.getName()){return true;}else{return false;}}public int hashCode(){return this.name.hashCode();//return this.name.hashCode()*this.age;}}


TreeSet类:

1、不保证元素的先后添加顺序,但是会对集合中的元素做排序操作.

2、底层才有红黑树算法(树结构,比较擅长做范围查询).

TreeSet要么才有自然排序,要么定制排序.

A) 自然排序:  要求在TreeSet集合中的对象必须实现java.lang.Comparable接口,并覆盖compareTo方法.

B) 定制排序:  要求在构建TreeSet对象的时候,传入一个比较器对象(必须实现java.lang.Comparator接口).在比较器中覆盖compare方法,并编写比较规则.

3TreeSet判断元素对象重复的规则:                                       

 compareTo/compare方法是否返回0.如果返回0,则视为是同一个对象.

Demo:

public class TreeSetDemo { public static void main(String[] args) {/*TreeSet<Animal> ts = new TreeSet<>();ts.add(new Animal("dog1",2));ts.add(new Animal("cat2",1));ts.add(new Animal("bird3",4));ts.add(new Animal("dog4",2));System.out.println(ts);*///[Animal [name=cat2, age=1], Animal [name=dog1, age=2], Animal [name=bird3, age=4]]  Animal[] a = {new Animal("dog1",2),     new Animal("cat2",1),     new Animal("cat3",1),     new Animal("dog4",3)};Arrays.sort(a);for (int i = 0; i < a.length; i++) {System.out.println(a[i]);}//Animal [name=cat2, age=1]Animal [name=cat3, age=1]Animal [name=dog1, age=2]Animal [name=dog4, age=3]} }class Animal implements Comparable<Animal>{private String name;private Integer age;Animal(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public int compareTo(Animal a) {if (this.age > a.getAge()) {return 1;}else if(this.age < a.getAge()) {return -1;}else {return 0;}}@Overridepublic String toString() {return "Animal [name=" + name + ", age=" + age + "]";}}


九、Map类(映射):

1Map的常用实现类:

A) HashMap: 采用哈希表算法,此时Map中的key不会保证添加的先后顺序,key也不允许重复.  key判断重复的标准是: key1key2是否equalstrue,并且hashCode相等.

B) TreeMap:采用红黑树算法,此时Map中的key会按照自然顺序或定制排序进行排序,,key也不允许重复.  key判断重复的标准是: compareTo/compare的返回值是否为0.

C) LinkedHashMap: 采用链表和哈希表算法,此时Map中的key会保证先后添加的顺序,key不允许重复.  key判断重复的标准和HashMap中的key的标准相同.

HashMapTreeMap以及LinkedHashMap都是线程不安全的,但是性能较高:

解决方案: Map m = Collections.synchronizedMap(Map对象);

Hashtable类实现线程安全的,但是性能较低.

哈希表算法:做等值查询最快.

数结构算法:做范围查询最快-->应用到索引上.

 

2一般的,我们定义Map,key都使用不可变的类(String),key作为value的唯一名称.

 

Demo:

public class MapDemo { public static void main(String[] args) {//利用Iterator输出Map(Map一般都是供查询,很少直接输出,但是一旦要输出必须按一下标准格式)/*Map<String, Object> map = new HashMap<String,Object>();map.put("lisi", "川大");map.put("zhangsan", "电子科大");map.put("wangwei", "北大");Set<Map.Entry<String, Object>> entrys = map.entrySet();for (Map.Entry<String, Object> entry : entrys) {String key = entry.getKey();Object values = entry.getValue();System.out.println(key+"<--->"+values);}*/ //需求:计算一个字符串中每个字符出现的次数:String str = "helowjfjsvnfdjfdfdddhsefew";//字符串本质是char[]char[] arr = str.toCharArray();Map<Character, Integer> map = new TreeMap<>();for (char ch:arr) {//判断当前字符是否在Map中的key存在if (map.containsKey(ch)) {//当前Map的key包含该字符,取出value值递增1,再存放进去Integer old = map.get(ch);map.put(ch, old+1);} else {//当前Map的key不包含该字符,取出value值为1map.put(ch, 1);}}System.out.println(map);} }


十、ListSetMap的选用:

1选用哪一种容器取决于每一种容器的存储特点以及当前业务的需求:

A) List:  单一元素集合.

         允许元素重复/记录元素的添加顺序.

B) Set:单一元素集合.

        不允许元素重复/不记录元素的添加顺序.

既要不重复,又要保证先后顺序:LinkedHashSet. 

C) Map: 双元素集合.如果存储数据的时候,还得给数据其为一个的一个名称,此时考虑使用Map.

2ListSet以及Map之间相互转换问题:

  List<String> list = new ArrayList<>();

  List转换为Set:

  Set<String> set = new HashSet<>(list);//此时会消除重复的元素.

  Set转换为List:

  List<String> list2 = new ArrayList<>(set );

  Map不能直接转换为ListSet(但是Map中的方法可以间接转换).

 

十一、集合工具类(Collections)

1为集合添加内容

List<String> all= new ArrayList<String>();

Collections.addAll(all,"haoren","huairen","person";

2反转

collections.reverse(all);

3替换

collections.replaceAll(all,"haoren","mz");

4排序

collections.sort(all);

5查找

collections.binarySearch(all,haoren);(先要排序,因为使用二分法)

6交换指定位置的内容

collections.swap(all,1,2);

原创粉丝点击