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当前位置为参照,还有下一个元素吗?
    1. 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

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当前位置为参照,还有下一个元素吗?
    1. 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学习)