java集合和泛型

# 集合存储结构

**集合和数组的区别**

**1. 数组能容纳基本数据类型和引用数据类型;集合只接收引用数据类型。

2. 数组的长度是固定的。【集合长度可变的。】

3. 数组可进行的操作很有限:

4.  集合是对象,有方法和属性可供调用,功能丰富了;面向对象的特性,封装,继承,多态。**

## 1.Collection接口

Collection接口中的方法

add(Objectionn o)添加一个元素

size()  元素的个数

addAll(Collection c)  添加一个集合对象的元素

contains(Object o)  是否包含该"o"元素

isEmpty()    是否为空

iterator()    迭代

remove(Object o)  删除对象

toArray()  返回数组

## 2. List接口

List集合中的元素都是有序可重复的集合

List接口中的方法

void add(int index, Object ele)            //指定下标添加元素

boolean addAll(int index, Collection eles) //指定下标添加集合

Object get(int index)                      //获取下标的元素

int indexOf(Object obj)                    //从左到右获取元素的下标

int lastIndexOf(Object obj)                //从右到左获取元素的下标(永远从0开始的)

Object remove(int index)                  //通过下标删除

Object set(int index, Object ele)          //修改下标的元素

List subList(int fromIndex, int toIndex)  //返回一个子集合(不包含toIndex下标)

**2.1、ArrayList**

有序,不唯一;有序是索引顺序;

*(1)遍历时按添加顺序;

*(2)内存原理:内存中分配的是连续的空间;有索引,

*          ArrayList是一个Object类型的数组;数组长度不够了,会生成更长的新数组;

*(3)性能:按索引查询,效率高;

*          按内容查询,效率低;

*          添加删除元素效率低;可能引起大量元素的位移;

/*

*ArrayList的遍历方法:

*1.for-each;

*2.普通for循环;操作索引;

*3.迭代器:

*  1)生成迭代器:Iterator it=list.iterator();//it初始位置在索引为0的元素之前;

*  2)it.hasNext():以it当前位置为参照,还有下一个元素吗?

*  3) it.next():先把it当前位置的下一个元素取出来;把it的位置往后移动一个元素;

*  4)it.remove():把it当前位置的元素删除。

*  5)在用迭代器遍历集合期间,不要用集合对象名对集合进行操作(如list.add(6)),会出现并发修改异常:java.util.ConcurrentModificationException。

```

public class Test2 {

      public static void main(String[] args) {

              List list = new ArrayList();

              list.add(1);

              list.add(2);

              list.add(3);

              list.add(4);

              list.add(5);

              // 集合的遍历;for-each;

//                for (Object obj : list) {

//                        System.out.println(obj.toString());

//                }


              //普通的for循环;

//                for(int i=0;i

//                        Object obj=list.get(i);

//                        System.out.println(obj);

//                }


              Iterator it=list.iterator();


              while(it.hasNext()){


                      Object obj=it.next();//把it原有位置的下一个元素取出来;把it的位置往后移动一个元素;

                      System.out.println(obj);

                      //list.add(6);会出现并发修改异常:java.util.ConcurrentModificationException。

                      it.remove();//it指向的是哪个元素,就删除哪个元素;

              }


              System.out.println(list.size());


      }

}

```

**2.2 LinkList**

.链表:LinkedList,物理空间上不连续,但逻辑上是连续的。

添加删除元素效率高;不会引起大量元素的位移;

*LinkedList的特点:有序,不唯一;有序是索引顺序;

*(1)遍历时按添加顺序;

*(2)内存原理:链表

*(3)性能:按索引查询,效率低;必须从第一个元素查起;

*        按内容查询,效率低;

*        添加删除元素效率高;不会引起大量元素的位移;

1.for-each;

2.普通for循环;操作索引;

3.迭代器:

```

public class Test {

      public static void main(String[] args) {

              // 创建一个容器对象;

              List list = new LinkedList();// 运用多态;

              List subList = new LinkedList();

              subList.add(1);

              subList.add(2);

              // 添加;

              Person p1 = new Person();

              Person p2 = new Person();

              // add(Object obj):Object做形参,可以接收不同的子类实参;运用多态;

              list.add(p1);

              list.add(p2);

              list.add("Hello");

              // 123--->Object obj=new Integer(123);添加数字相当于自动装箱;

              list.add(123);

              list.add(2, "java");

              list.addAll(subList);

              list.addAll(2, subList);

              // 删除;

              // list.remove(2);//2是索引位置;

              // list.remove("java");//如果有多个"java",就删除第一个;

              // list.remove(new Integer(2));

              // list.removeAll(subList);//删除的是所有和subList里相同的元素,删除的是与subList的交集;

              // 改;

              list.set(1, "today is perfect");

              // list.clear();

              //list.retainAll(subList);// 取与subList交集;

              // 查;

              System.out.println(list.size());// 实际元素的个数,不是集合的总容量;

              // System.out.println(list.get(0));//得到索引为0的位置的元素;

              System.out.println(list.contains(p1));

              System.out.println(list.isEmpty());

              // 集合的遍历;

              for (Object obj : list) {

                      System.out.println(obj.toString());

              }

              // 普通的for循环;

              for (int i = 0; i < list.size(); i++) {

                      Object obj = list.get(i);

                      System.out.println(obj);

              }

              Iterator it = list.iterator();

              while (it.hasNext()) {

                      Object obj = it.next();// 把it原有位置的下一个元素取出来;把it的位置往后移动一个元素;

                      System.out.println(obj);

                      // list.add(6);会出现并发修改异常:java.util.ConcurrentModificationException。

                      it.remove();// it指向的是哪个元素,就删除哪个元素;

              }

              System.out.println(list.size());

      }

}

```

## 3.Set接口

  Set接口    元素无序(hashCode())、不可重复的集合

    HashSet    LinkedHashSet    TreeSet

1)HashSet  无序(hashCode())、不可重复的集合  hashCode()  equals()

  *HashSet的特点:无序,唯一;

*(1)遍历是不可预知顺序;

*(2)内存原理:哈希表,用hashcode和equals()方法;

*(3)性能:查询效率高;

*        添加删除效率高;

*(4)自定义类,建议重写hashcode()和equals()方法,成对重写。

*    告诉程序你的比较策略。

*    不重写,就用Object的方法了。

1. HashSet怎么保证元素的唯一性呢?

*先用hashcode计算出地址,如果没有元素,就存进去;如果已有元素,就用equals(),如果true,不添加了;

*如果false,就添加。

*

*hashcode相同,元素不一定相同;再用equals(),true才是相同的。

*hashcode不同,元素一定不同。

2.遍历:

*  1)for-each:

*  2)迭代器:Iterator it=set.iterator();

*3.添加:

*  set.add(Object obj);

*  set.addAll();

*  删除:

*  set.remove(Object obj);

*  set.removeAll();

*  查:

*  set.isEmpty();

*  set.size();

*  set.clear();

*  set.contains();

*  set.containsAll();

*  set.retainAll();

*  转换:

*  //把集合类型转成Object类型的数组;

      Object[] objArr=set.toArray();

* */

```

public class TestHashSet {

      public static void main(String[] args) {


              //创建一个HashSet对象;

              Set set=new HashSet();


              //添加;

              System.out.println(set.add(23));//true;

              set.add(36);

              set.add(48);

              set.add(77);

              set.add(86);

              set.add(67);

              set.add(76);

              System.out.println(set.add(23));//false;

              set.add(56);

              set.add(78);

              set.add(47);


              //删除;

              set.remove(47);



              //改;

              //查;

              System.out.println(set.size());

              System.out.println(set.isEmpty());

              //set.clear();


              //遍历;

              Iterator it=set.iterator();


              while(it.hasNext()){

                      Object obj=it.next();

                      System.out.println(obj);

              }

              System.out.println("==========================");

              //用for-each遍历;

              for(Object obj:set){

                      System.out.println(obj.toString());

              }


              //把集合类型转成Object类型的数组;

              Object[] objArr=set.toArray();

              System.out.println(Arrays.toString(objArr));

      }

}

```

    2)LinkedHashSet:遍历输出的内容和添加的顺序一致

    3)TreeSet

      * 1.添加元素必须是同一类型,否则遍历出错

      * 2.遍历输出顺序按默认顺序(从小到大)如:String,Integer等

      * 3.自然排序,必须要实现Comparable,compareTo方法,实现排序

      * 4.定制排序,需要实现接口Comparator接口

*TreeSet:有序,唯一;有序,不是添加顺序,是大小顺序;

*(1)遍历时是大小顺序;

*(2)内存原理:二叉树;

*(3)查询(按内容查询),效率中等;在ArrayList和HashSet之间;

*    添加删除,效率中等。

*(4)如果是自定义类,要实现Comparable接口;

*    告诉程序你的比较策略;

*    否则会报:java.lang.ClassCastException:Student--->Comparable;

*   

*    Set treeSet=new TreeSet();

*

*(5) 也可以实现Comparator接口;

```

*      StuScoreComp sComp=new StuScoreComp();

              Set treeSet = new TreeSet(sComp);

public class TestTreeSet {

      public static void main(String[] args) {


              //创建TreeSet对象;

              Set treeSet=new TreeSet();


              //添加;

              treeSet.add(50);

              treeSet.add(35);

              treeSet.add(78);

              treeSet.add(27);

              treeSet.add(45);

              treeSet.add(56);

              treeSet.add(40);

              treeSet.add(45);

              treeSet.add(48);

              treeSet.add(90);


              //遍历;

              Iterator it=treeSet.iterator();


              while(it.hasNext()){

                      Object obj=it.next();

                      System.out.println(obj);


              }

      }

}

```

## 4.Map接口

*Map特有的三个方法:

*map.keySet();获取key的集合;

*map.values();获取value的集合;

*map.entrySet();获取key和value的集合;

  Map接口      key-value对”的集合

      HashMap(效率高)          LinkedHashMap    TreeMap  HashTable(古老的类,基于线程安全,效率低)

    Properties  load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。

*HashMap:

*1.是键值对,每个元素包含两部分:key,value;

*2.key和value是一一对应的;

*3.key是无序,唯一的;如果添加了重复的key,不报错,后面的会覆盖前面的;

*4.value是无序,不唯一的;

*5.key和value都可以是null。

*6.如果key是自定义类:要重写hashCode()和equals()方法;

*  告诉程序你的比较策略;

内存原理:key部分与HashSet原理相同,无序,唯一;

                事实上,HashSet底层调用的是HashMap.

              /*

*HashMap底层是一个Entry类型的数组;

*Entry

*Entry:key,value和指向下一个Entry元素的引用。

*

*

```

*/

public class TestHashMap1 {

      public static void main(String[] args) {


              Map map=new HashMap();


              map.put(1, "罗马假日");

              map.put(3, "三国演义");

              map.put(2, "炼金术士");


              //遍历:

              Set entrySet=map.entrySet();


              Iterator> it=entrySet.iterator();


              while(it.hasNext()){

//                        it.next().getKey();

//                        it.next().getValue();

                      Entry entry=it.next();

                      System.out.println(entry);

              }


      }

}

```

/*

*TreeMap: 有序(大小顺序),唯一;按key排序;

*如果key是自定义类:要实现Comparable或Comparator接口;

*告诉程序你的比较策略;

*

*/

```

import java.util.TreeMap;

public class TestTreeMap {

      public static void main(String[] args) {


              Map map=new TreeMap();


              map.put(16, "炼金术士");

              map.put(2, "炼金术士");

              map.put(1, "罗马假日");

              map.put(3, "三国演义");

              map.put(2, "围城");


              //遍历:

              Set entrySet=map.entrySet();


              Iterator> it=entrySet.iterator();


              while(it.hasNext()){

                      Entry entry=it.next();

                      System.out.println(entry);

              }


      }

}

```

## 5.迭代器

迭代器:

*  1)生成迭代器:Iterator it=list.iterator();//it初始位置在索引为0的元素之前;

*  2)it.hasNext():以it当前位置为参照,还有下一个元素吗?

*  3) it.next():先把it当前位置的下一个元素取出来;把it的位置往后移动一个元素;

*  4)it.remove():把it当前位置的元素删除。

*  5)在用迭代器遍历集合期间,不要用集合对象名对集合进行操作(如list.add(6)),会出现并发修改异常:java.util.ConcurrentModificationException。

list.iterator():

(1) iterator()不是Collection自己的方法,是继承自接口Iterable;

(2) Iterator iterator();返回值是Iterator类型的;

(3)  Iterator: 是一个接口类型,它里面的三个方法:hasNext();

                                                                              next();

                                                                              remove();

(4)遍历[集合]时底层调用Iterator完成操作。

## 6.Collectiongons工具类

/*

*1.Collections:

*  1)和Arrays一样,是专门用来操作集合的工具类;

*  2)大部分方法 都是静态的,可以通过类名直接调用;

*  3)构造方法私有化,不能创建Collections的对象;

*2.Collections的常用方法:

*  1)Collections.addAll(list,60,50);

*  //如果是自定义对象,要给出比较策略,实现Comparable接口;

*  2)Collections.sort(list);

*  //用于排好序的集合上;查到就返回索引值,没查到就返回-(应该在的位置+1);

*  3)int index=Collections.binarySearch(list, 67);

*  4)Collections.copy(list, list2);

*  5)int max=Collections.max(list);

      6)int min=Collections.min(list);

      7)Collections.fill(list, 888);

      8)Collections.reverse(list);

*  9)List list3 = Collections.synchronizedList(list);

*

*3.Collection和Collections的区别:

*  1)Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口List和Set。

  2)Java中还有一个Collections类,专门用来操作集合类 ,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

*/

```

public class TestCollections {

      public static void main(String[] args) {


          ArrayList list=new ArrayList();


          //添加Integer类型的元素;

          list.add(3);

          list.add(4);

          list.add(1);

          list.add(2);

          list.add(5);


          Collections.addAll(list,60,50);

          //Collections.sort(list);

          //int index=Collections.binarySearch(list, 50);

          ArrayList list2=new ArrayList();

          Collections.addAll(list2,11,12,13,14);

          Collections.copy(list, list2);

          //Collections.fill(list, 888);

          //Collections.reverse(list);

          int max=Collections.max(list);

          int min=Collections.min(list);

          System.out.println(max+" "+min);

          //System.out.println(index);


          //遍历:

          Iterator it = list.iterator();

              while (it.hasNext()) {

                      System.out.println(it.next());

              }


              //ArrayList是线程非同步,程序员可以自己写代码把ArrayList转成同步的操作;

              List list3 = Collections.synchronizedList(list);

      }

}

```

你可能感兴趣的:(java集合和泛型)