黑马程序员——集合

来源:互联网 发布:移动硬盘分区隐藏软件 编辑:程序博客网 时间:2024/05/23 17:50

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

 

 

 

 

 

一、Collection单列集合

()List接口的实现类

1ArrayList

(1)构造函数:

ArrayList arr = new ArrayList();    //创建一个初始容量为10的空列表

ArrayList arr1 = new ArrayList(int x);  //创建初始容量为指定大小x的空列表

(2)常用方法:

add(Object obj);      //向集合中存入元素

get(int index);        //获取指定角标位置的元素

size( );          //返回集合中元素的个数

(3)集合的迭代:借助迭代器对象

List<String> list = new ArrayList<String>(); //创建集合

    list.add("aa");               //向集合中添加元素

    list.add("bb");

    Iterator<String>iter = list.iterator();  //获得与集合对象匹配的迭代器

    while(iter.hasNext()) {                //判断是否有下一个元素

       String string= iter.next();      //迭代出下一个元素

       System.out.println(string);

    }

next()方法:让迭代器指向下一个元素,并返回当前指向的元素。

 

注意:集合在迭代期间,不能调用集合的方法增删元素,否则会并发访问异常:(ConcurrentModificationException)。如果要增删元素,需用迭代器的方法。

 

a.删除元素:Iteratorremove方法。

ArrayList<String> arr = new ArrayList<String>(); 

    arr.add("aa");

    arr.add("bb");

    arr.add("cc");

    Iterator<String> iter = arr.iterator();

    while (iter.hasNext()) {

       String s = iter.next();

       if("bb".equals(s))   //常量写在equlas前面,防止空指针异常

           iter.remove();   

    }

    System.out.println(arr);

 

 

b.增加元素:使用ListIteratoradd方法

ArrayList<String> arr = new ArrayList<String>();

    arr.add("aa");

    arr.add("bb");

    arr.add("cc");

    ListIterator<String> listiter = arr.listIterator();

    while (listiter.hasNext()) {

       String s = listiter.next();

       if("bb".equals(s))

           listiter.add("xxx");

    }

    System.out.println(arr);

2Vector

线程安全,但是效率低。且集合对象不会用作成员变量,而对象作为方法的局部变量不会有线程安全的问题,所以已被ArrayList淘汰。

迭代:Enumeration,只适用于Vector集合

Vector<String> v = new Vector<String>();

    v.add("aa");

    v.add("bb");

    Enumeration<String> e = v.elements();

    while(e.hasMoreElements()) {

       String str = e.nextElement();

       System.out.println(str);

    }

3LinkedList集合

addFirst(“aa”); (效率高)   add(0, ”aa”);

removeFirst(); (效率高)    remove(0);

addLast(“dd”);            add(“dd”);

removeLast();             remove(角标);

()Set接口的实现类

1HashSet:通过哈希算法保证无重复元素

HashSet<Person> hashSet = newHashSet<Person>();

a.重复元素的hashCode()返回的哈希值必须一样。

      保证重复元素的存储位置在同一区间,有机会进行equals比较。

  为此,需要重写hashCode()方法。如果不重写hashCode()方法,不同对象,即

使属性相同,默认返回的哈希值也不一样,存储位置不在同一区间,无法进行

equals比较。

@Override

publicint hashCode() {

  returnthis.name.hashCode() +this.age*31;//避免x+yy+x得出的值相同

}

b.重复元素进行equals()比较返回的值为true

   因此,必须重写equals()方法。   

 

子类:LinkedHashSet。元素有序的HashSet

LinkedHashSet<String> linked = new LinkedHashSet<String>();

    Collection<String>c = new ArrayList<String>();

    c.add("aa");

    c.add("bb");

    linked.addAll(c);    //特殊方法。addAll(Collection c)

2TreeSet

新存的元素与原来的元素比较,如果比原来的元素打,存入右边;如果比原来的元素小,存入左边;如果与原来的一样,不存。

 

实现排序的方法:

(1)按照自然顺序进行排序,元素实现Comparable接口的compareTo()方法。

publicclass PersonimplementsComparable {

    private Stringname;

    privateintage;

    @Override

    publicint compareTo(Object o) {

       Person p = (Person)o;

       //先按照名字比较

       int num =this.name.compareTo(p.name);

       if(num != 0)

           return num;

       //如果名字相同,按照年龄比较

       returnthis.age - p.age;

    }

}

(2)按照比较器排序,实现Comparator接口的compare()方法。

在创建TreeSet对象时,传入比较器对象

TreeSet<Person> treeSet =new TreeSet<Person>(new MyComparator());

 

class MyComparatorimplementsComparator {

    @Override

    publicint compare(Object o1, Object o2) {

       Person p1 = (Person) o1;

       Person p2 = (Person) o2;

       //先比较年龄

       int num = p1.getAge() - p2.getAge();

       if (num != 0)

           return num;

       //如果年龄相同,比较名字

       return p1.getName().compareTo(p2.getName());

    }

}

注意:如果两种方式都实现,则以比较器的排序规则为准。

二、Map双列集合

Map存储了一系列的键值的映射关系。put(keyvalue)

()HashMap:哈希算法实现

HashMap<String , Person> hashMap = newHashMap<String, Person>();

1、向HashMap中存入元素:put(key, value)

   如果向HashMap中存入相同的key,新存入的value值会覆盖之前的value值。

2、获取HashMap中的元素

a.获得所有的key   Set<String> keys =hashMap.keySet();

b.获得所有的value  Collection<Person> values =hashMap.values();

c.通过key获得value Person value = hashMap.get(key);

3、迭代HashMap集合的元素

(1)获得所有的key组成的Set集合,遍历集合,根据key获得value

HashMap<String, Person> hashMap = new HashMap<String, Person>();

Set<String> keys = hashMap.keySet();    //获得所有的key

    for (String key : keys) {       

        Person value =hashMap.get(key);     //根据key获得value

        System.out.println(key +":" + value);

    }

(2)获得所有的Entry(键值对)对象组成的Set集合,遍历,分别获得keyvalue

Set<Entry<String, Person>> entrys = hashMap.entrySet();

    for (Entry<String, Person> entry : entrys) {

       String key = entry.getKey();

       Person value = entry.getValue();

       System.out.println(key +":" + value);

    }

子类:LinkedHashMap.元素有序的HashMap

()TreeMap:二叉树实现,按照key排序

 

()HashTable:哈希算法实现,线程安全,已被HashMap淘汰

子类:Properties:操作配置项。

      此集合没有泛型。由于配置文件都是String类型的,Propertieskeyvalue都是String类型的。

1、向Properties中存入元素:

  setProperty(String key, String value)

2、取出Properties集合中的元素:

  getProperty(String key);

3、返回该属性列表中所有键的枚举

  propertyNames( );

例子:

Properties props = new Properties();

props.setProperty("a", "aaaaaa");  //向集合中存入元素

props.setProperty("b","bbbbbb");

props.setProperty("c","cccccc");            //返回该属性列表中所有键的枚举

Enumeration<String> names=(Enumeration<String>)props.propertyNames();

while(names.hasMoreElements()) {

 String name =names.nextElement();

    String value = props.getProperty(name);  //根据key获得value

    System.out.println(name+":"+value);

}

三、Iterator 迭代器:用来迭代集合中的元素

Iterator:在迭代的过程中可以调用remove()方法删除元素,移除迭代器指向的集合被迭代的最后一个元素。 

子类:ListIterator:在迭代的过程中可调用add()方法增加元素

四、增强for循环

用于遍历集合中的元素,不能用于修改集合中的元素。

循环次数就是容器中元素的个数,每次循环迭代容器中的一个元素,将元素赋值给变量。

五、可变参数

定义:类型...变量

理解:可变参数对调用者来说可以传入0~多个参数。

      可变参数对方法而言就是一个数组,JVM将调用者传入的参数封装成一个数组传递给方法

//n个参数的和

    privatestaticint sum(int...nums) {

      

       int sum = 0;

       for(int i=0;i<nums.length;i++) {

           sum+=nums[i];

       }

       return sum;

    }

注意事项:

(1)可变参数必须位于方法的最后一个参数,一个方法只能有一个可变参数

(2)使用可变参数会有版本冲突问题,此时会向下兼容jdk1.4

String[] s1 = {"aa","bb"};

String[] s2 = {"a","b"};

a   

List<String[]> list1 = Arrays.asList(s1,s2);

// 只符合jdk1.5的语法,将数组存入集合,2个元素

System.out.println(list1);    //打印出两个数组的首地址

b   

List<String> list2 = Arrays.asList(s1); 

//同时符合jdk1.4jdk1.5的语法,向下兼容jdk1.4,拆分数组,将s1数组的两个元素存入集合 asList(Object[]arr)    asList(T...t)

        arr中的元素作为一个列表    T类型的t作为列表

System.out.println(list2); //打印 [aa,bb]

c.

List<Object> list2 =Arrays.asList((Object)s1);//数组向上提升为Object对象

System.out.println(list2); //打印s1对象的首地址

 

List<Object> list2 =Arrays.asList(new Object[]{s1});

 //按照jdk1.4的语法,将s1对象作为数组的一个元素

System.out.println(list2); //打印 s1对象的首地址

六、泛型

1、泛型在集合中使用:

   在集合中使用泛型,实际上就是为集合贴了一个标签,限定了存入集合的对象的类型,可以提高安全性,不必进行类型强转。

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

注意事项:

(1)等式两边的泛型必须保持一致。

   编译器在检查语法是看等式左边变量的类型。

   程序运行期间,对象的类型取决于等式右边。

(2)可以只在等式一边定义泛型。原因是泛型是JDK1.5的新特性,为了实现向下兼容。

2、泛型的概念:

(1)在类上使用泛型

需求:一个类的多个方法用到的类型可以使任意类型,但是必须是同一种类型。

泛型可以解决上述问题。泛型是一种不确定的变化的类型。

泛型可以理解为一种类型变量,形参只能传入类型。

正常情况下使用泛型应该传入参数,但是由于泛型是在JDK1.5之后出现的,为了实现向下兼容,泛型允许不传参,如果不传参,JVM在编译时传入参数Object

class Demo {

    publicstaticvoid main(String[] args) {

       QQFarm<Gua> farm = new QQFarm<Gua>();

       farm.plant(new Gua());

       Gua gua = farm.get();

    }

}

 

class Gua {            //定义一个类型

}

 

//可以种植任何东西,也可以收获任何东西,但种植和收获的必须是一种东西

class QQFarm<T>

    //种植

    publicvoid plant(T obj) {

    }

 

    //收获

    public T get() {

       returnnull;

    }

}

(2)泛型方法

在类上声明的泛型对类的静态成员无效。如果在静态方法中所需要使用泛型,泛型要在方法的返回值前面,紧挨着返回值的地方加以声明。

publicstatic<T>T sum(T x, T y){

       //判断x是否具备自然顺序

       if(!(xinstanceof Comparable))

           thrownew RuntimeException("不具备自然顺序,不能比较");

      

       Comparable com = (Comparable)x;

       return com.compareTo(y)>0?x:y;

    }

 

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

原创粉丝点击