java基础系列05--集合(1)

2019-01-14  本文已影响9人  addin_gao

JAVA 集合

集合由来:

数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少

数组和集合的区别:

区别1 :

区别2:

Collection集合

集合.png
* boolean add(E e)
* boolean remove(Object o)
* void clear()
* boolean contains(Object o)
* boolean isEmpty()
* int size()
    
public static void main(String[] args){
        Collection c1 = new ArrayList();  // Collection是接口,父类引用指向子类对象
        boolean b1 = c1.add("abc");     // true
        boolean b2 = c1.add(new Person());   // true
        c1.add(true);  // true  添加任何都能返回true
        System.out.println(c1); //ArrayList 父类重写了toString方法 [abc, com.test.Person@15db9742, true]
        System.out.println(c1.remove("abc")); //true 删除成功返回true,否则为false
        System.out.println(c1.contains("a"));// false 
        System.out.println(c1.size()); //2 集合中元素个数
        
}

集合转数组并且进行遍历(了解):

public class Student {
    public static void main(String[] args){
        Collection c = new ArrayList();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        Object[] arr = c.toArray();
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]); // a b c d
        }
        c.clear();
        c.add(new Person("张三",12));
        c.add(new Person("李四",13));
        c.add(new Person("王五",14));
        c.add(new Person("赵六",15));
        Object[] arr1 = c.toArray();
        for(int i =0;i<arr1.length;i++){
//          System.out.println(arr1[i].getName()); //此时arri[i] 的类型提升到了Object,要调用对象特有的方法需要向下转型
            Person p = (Person)arr1[i];  // 需要向下转型
            System.out.println(p.getName()+"----"+p.getAge());  // 张三----12   李四----13   王五----14   赵六----15
        }
    }
    
}

Collection集合的带All的方法:

boolean addAll(Collection c) // c1.addAll(c) 将集合c中的每个元素添加到C1
boolean removeAll(Collection c) // c1.removeAll(c) 删除c1中含有的c元素,删除交集 
boolean containsAll(Collection c) //c1.containsAll(c) c1是否包含c,和顺序有关
boolean retainAll(Collection c) // c1.retainAll(c) c1保留和c的交集,其余删除,调用的集合改变则返回true,不变则返回false

集合的遍历之迭代器遍历:

Collection c = new ArrayList();
c.add("a");
c.add("b");
c.add("c");
c.add("d");
Iterator it = c.iterator(); //获取迭代器
while(it.hasNext()){ // 若有元素,则返回true,没有返回false
    System.out.println(it.next()); // a b c d
}

List 集合特有功能

* boolean add(E element) // 添加元素
* void add(int index,E element)//根据索引添加元素
* E remove(int index)  //根据索引移除元素
* E get(int index)  //根据索引获取元素,可以遍历List集合
* E set(int index,E element) // 修改指定位置的元素

并发修改异常的解决方法 (ListIterator):

public static void main(String[] args){
        List c = new ArrayList();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
//      Iterator its = c.iterator(); //获取迭代器
//      while(its.hasNext()){
//          if( its.next() == "c"){
//              c.add("xx"); //报错 java.util.ConcurrentModificationException
//          }
//      }
        ListIterator it = c.listIterator(); // 获取迭代器(list集合特有的)
        while(it.hasNext()){
            if(it.next() == "c"){
                it.add("xx");
            }
        }
        System.out.println(c); // [a, b, c, xx, d]
        
}

List的三个子类的特点:

ArrayList:
​ 底层数据结构是数组,查询快,增删慢。
​ 线程不安全,效率高。

Vector:
​ 底层数据结构是数组,查询快,增删慢。
​ 线程安全,效率低。

Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
​ 底层数据结构是链表,查询慢,增删快。
​ 线程不安全,效率高。

查询多用ArrayList

增删多用LinkedList

Vector集合(被替代掉了,面试用)

vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。

Vector v = new Vector();
v.addElement("a");
v.add("b");
ListIterator its = v.listIterator();
while(its.hasNext()){
    System.out.println(its.next());
}
System.out.println(v);

ArrayList

public static void main(String[] args){
    // 去除ArraryList的重复项
    ArrayList a = new ArrayList();
    a.add("a");
    a.add("b");
    a.add("b");
    a = getSingleList(a);
    System.out.println(a); //[a, b]
}
public static ArrayList getSingleList(ArrayList arr){
    Iterator i = arr.iterator();
    ArrayList a = new ArrayList();
    while(i.hasNext()){
        Object temp = i.next();
        if (!a.contains(temp)){ // 若集合中保存的是自定义对象则自定义对象需要重写equals方法
            a.add(temp);
        }
    }
    return a;
}

LinkedList的特有功能:

public static void main(String[] args){
        LinkedList l = new LinkedList();
        l.addFirst("a"); // a
        l.addFirst("b"); // b a
        l.addLast("c"); //  bac
        l.add("d");   //bacd
        Object first = l.getFirst(); // b
        Object last = l.getLast(); // d
        l.removeFirst();  //delete the "b"
        l.removeLast(); // delete the "d" 
        Object s = l.get(1);  // 根据索引获取对应的元素,
        System.out.println(l); // [a,c]
        System.out.println(s); // c

}

泛型:

限定某个集合的存储元素类型,提高安全性(将运行期的错误转换到编译期) ,省去强转的麻烦

规定:<>中放的必须是引用数据类型前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)

//ArrayList<Person> arr1 = new ArrayList<>();  后面的泛型可以省略不写(1.7的新特性菱形泛型)
//ArrayList<int> arr2 = new ArrayList<Person>(); 错误,泛型限定一定要是引用数据类型,可以写Integer
//ArrayList<Object> arr3 = new ArrayList<Person>();  报错,前后泛型不一致,而且泛型定义成Object无意义
ArrayList<Person> arr = new ArrayList<Person>();
arr.add(new Person("张三",11));
arr.add(new Person("李四",13));
        
Iterator<Person> i = arr.iterator(); // 使用泛型限定元素类型
while (i.hasNext()){
    Person p = i.next();
    System.out.println(p.getAge()+"----"+p.getName());
}

给自己的类加泛型

class Tool<E>{
    private E e;
    public E getObj(){
        return e;
    }
    public void setObj(E e){
        this.e = e;
    }
    public<T>void show(T t){  // 方法泛型需要与类的一直,如果不一致,则需要在方法上声明泛型
        System.out.println(t);
    }
    public static<W> void shows(W e){ // E是在创建对象的时候才赋值,但是静态则是不用创建对象就能直接调用的
       // 所以静态方法必须要给出自己的泛型
        System.out.println(W); // 可以写E,这里写E的话和类的E就是不同的变量,只是名字相同
    }
}

泛型接口:

interface Inter<T>{
    public void show (T t);
}
class Demo implements Inter<String>{

    @Override
    public void show(String t) {
        System.out.println(t);
    }   
}

泛型高级之通配符(了解):

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

增强for 循环遍历数组和集合

增强for 循环底层依赖的是迭代器

public static void main(String[] args){
       // 增强 for循环遍历数组
        int[] arr = new int[]{11,22,33,44};
        for (int i : arr) {
            System.out.println(i); //11 22 33 44 
        }
        // 增强 for循环遍历集合
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        for (String string : list) {
            System.out.println(string);  // aa bb cc dd
        }   
}

三种在遍历的时候删除集合元素:

        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
//      -------第一种删除方式-------------
//      for (int i = 0; i < list.size(); i++) {
//          if ("b".equals(list.get(i))){
//              list.remove(i);
//              i--; // 需要加这句,才能删除2个b,不加只能删除一个
//          }
//      }
        
//      -------第二种删除方法-------------
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            if ("b".equals(it.next())){
                it.remove(); // 不能使用集合的删除,只能使用迭代器的删除,否则并发修改异常
            }
        }
//      -------第三中删除方法( 不行并发修改异常)--------
//      for (String string : list) {
//          if ("b".equals(string)){
//              list.remove("b");
//          }
//      }

JDK1.5的可变参数:

如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

    public static void main(String[] args){
        int[] arr = new int[]{1,2,3,4};
        print(arr);  // 结果都一样
        print(1,2,3,4);
    }
    public static void print(int... arr){
        // 可变参数,这里的 arr就是一个数组
        for (int i : arr) {
            System.out.println(i);
        }
    }

Arrays工具类的asList()方法的使用

public static void main(String[] args){
        Integer[] arr = {11,22,33,44};
        // 将数组看作集合去使用,但是不能使用集合的增加和删除方法,其他的方法可以使用
        List<Integer> list = Arrays.asList(arr);
        //list.add(55); // 编译不报错,但是增加和删除会报错,不能操作
        //list.remove(1);// 编译不报错,但是增加和删除会报错,不能操作其余方法可以
        System.out.println(list.get(1)); // 22 
}

// 集合转为数组
public static void main(String[] args){
       ArrayList<String> arr = new ArrayList<String>();
       arr.add("a");
       arr.add("b");
       arr.add("c");
       String[] arrs = arr.toArray(new String[0]);
       for (String string : arr) {
         System.out.println(string); 
       }
}
上一篇下一篇

猜你喜欢

热点阅读