Java语言基础----常用API03(Collection集合)

集合和数组一样,可以保存一组元素,但是集合将元素的操作都封装成了方法,操作简便。
集合只能存放引用类型


java.util.Collection是所有集合的顶级接口,里面定义了所有集合都必须具备的功能方法
集合有两类常用的子类:
 * java.util.List:可重复的集合,且有序。通常我们称它为"线性表"
 * java.util.Set:不可重复的集合。linkedhashset是有序集合。
上述两个都是接口,而元素是否重复取决于元素自身的equals方法,即:Set集合中不会存在
两个元素equals比较为true的情况。

Collection常用方法

public class CollectionDemo1 {
    public static void main(String[] args) {
        //Collection c = new ArrayList();
        Collection c = new HashSet();//java.util.HashSet,不可重复的集合
        //集合只能存放引用类型
//        c.add(123);//会触发自动装箱特性
        /*
            boolean add(E e)
            向当前集合中添加一个元素,如果该元素成功添加则返回true,否则返回false
         */
        c.add(new Point(1,2));
        c.add(new Point(3,4));
        c.add(new Point(5,6));
        c.add(new Point(7,8));
        c.add(new Point(9,0));
        c.add(new Point(1,2));//重复元素无法放入Set集合两次
        /*
           集合重写了toString方法,格式为:
           [元素1.toString(), 元素2.toString(), 元素3.toString(), ....]
         */
        System.out.println(c);
        /*
            int size()
            返回当前集合的元素个数
         */
        int size = c.size();
        System.out.println("size:"+size);
        /*
            boolean isEmpty()
            判断当前集合是否为一个空集.当size为0时,返回true。
         */
        boolean isEmpty = c.isEmpty();
        System.out.println("是否为空集:"+isEmpty);

        Point p = new Point(1,2);
        /*
            boolean contains(Object o)
            判断当前集合是否包含给定元素。
            元素是否包含取决于该元素是否与集合现有元素存在equals比较为true的情况
         */
        boolean contains = c.contains(p);
        System.out.println("是否包含该元素:"+contains);

        /*
            remove方法删除元素时也是删除与集合中equals比较为true的元素。
            注:对于List而言,由于可以存放重复元素,对这种情况仅会删除一次。
         */
        c.remove(p);
        System.out.println(c);
        /*
            void clear()
         */
        c.clear();
        System.out.println(c);//[]
        System.out.println("size:"+c.size());//0
        System.out.println("是否为空集:"+c.isEmpty());//true
    }
}
/**
 * 集合间的操作
 */
public class CollectionDemo4 {
    public static void main(String[] args) {
        Collection c1 = new HashSet();
        c1.add("java");
        c1.add("c++");
        c1.add(".net");
        System.out.println("c1:"+c1);
        Collection c2 = new ArrayList();
        c2.add("android");
        c2.add("ios");
        c2.add("java");
        System.out.println("c2:"+c2);
        /*
            boolean addAll(Collection c)
            将给定集合中的所有元素添加到当前集合中(取并集)
            操作后当前集合发生了改变则返回true
         */
        c1.addAll(c2);
        System.out.println("c1:"+c1);
        System.out.println("c2:"+c2);

        Collection c3 = new ArrayList();
        c3.add("c++");
        c3.add("ios");
        c3.add("php");
        System.out.println("c3:"+c3);
        /*
            boolean containsAll(Collection c)
            判断当前集合是否包含给定集合中的所有元素
         */
        boolean containsAll = c1.containsAll(c3);
        System.out.println("包含所有:"+containsAll);
        /*
            取交集
         */
        c1.retainAll(c3);//c1有变化,c3不变
        System.out.println("c1:"+c1);
        System.out.println("c3:"+c3);
        /*
            删除交集。将c1中与c3的共有元素删除(c3不受影响)
         */
        c1.removeAll(c3);
        System.out.println("c1:"+c1);
        System.out.println("c3:"+c3);
    }
}

 集合与内存之间的关系

public class CollectionDemo3 {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        Point p = new Point(1,2);
        c.add(p);//将p元素存入集合
        System.out.println("p:"+p);//(1,2)
        System.out.println("c:"+c);//[(1,2)]

        p.setX(2);//将p对象中的x属性改为2
        System.out.println("p:"+p);//(2,2)
        System.out.println("c:"+c);//[(2,2)]
    }
}

集合遍历方式:迭代器模式

对应方法:
Iterator iterator()
java.util.Iterator是迭代器接口,定义了迭代器遍历集合的基本操作,所有的集合都提供了一个用于遍历自身元素的迭代器实现类,我们无需记住他们的名字,用多态的思想将他们统一看做是Iterator即可。迭代器遍历集合遵循的步骤:问hasNext()->取.next()->删it.remove()。其中删除不是必须操作。

迭代器在遍历的过程中不能通过集合的方法增删元素,否则迭代器会抛出并发修改异常:java.util.ConcurrentModificationException

public class IteratorDemo {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add("one");
        c.add("#");
        c.add("two");
        c.add("#");
        c.add("three");
        System.out.println(c);
        //获取迭代器
        Iterator it = c.iterator();
        /*
            boolean hasNext()
            判断集合是否还有"下一个"元素可以遍历。迭代器的起始位置可以理解为是集合第一个
            元素位置之前。因此第一次调用hasNext()就是判断集合是否有第一个元素。
            E next()
            获取集合中"下一个"元素。获取后迭代器的位置会向后移动一个元素位置
         */
        while(it.hasNext()){
            String e = (String)it.next();
            System.out.println(e);
            if("#".equals(e)){
                /*
                    迭代器在遍历的过程中不能通过集合的方法增删元素,否则迭代器会
                    抛出并发修改异常:
                    java.util.ConcurrentModificationException
                 */
//                c.remove(e);
                /*
                    迭代器提供了remove方法可以将本次通过next方法获取的元素从集合
                    中删除。
                 */
                it.remove();
            }
        }
        System.out.println(c);
    }
}

集合遍历方式:增强型for循环

语法: 循环遍历时会被编译器改回成传统for循环遍历
for(元素类型 e : 集合或数组){
        //执行代码块
}

迭代器与增强型for循环的区别:

在编译的时候,如果遍历的是数组,编译器会将增强型for循环改为for循环的形式;如果遍历的是集合,编译器会将增强型for循环改为迭代器的形式,而且直接使用迭代器可以对集合元素进行删除操作,而增强型for循环不可以进行此操作。数组增删操作不受限制。

public class NewForDemo {
    public static void main(String[] args) {
        String[] array = {"one","two","three","four","five"};
        for(int i=0;i<array.length;i++){
            String s = array[i];
            System.out.println(s);
        }
        for(String s : array){
            System.out.println(s);
        }
        /*
            JDK5之后还推出了一个特性:泛型
            泛型也称为参数化类型,它的原型就是Object,泛型的目的是让我们将定义的Object
            类型当做什么看待。
            例如下面的集合中保存的每个元素都是用Object接收的,但是集合将它改成了E类型
            这样一来,我们在使用集合时可以告知集合应当将E当做什么类型看待。
         */
        Collection<String> c = new ArrayList<>();
        c.add("一");//编译器会检查传入的E对应的实参是否为E指定的实际类型
        c.add("二");
        c.add("三");
//        c.add(1);//当实参不符合E指定的实际类型时,编译不通过

        //新循环遍历集合就是迭代器,编译器会将其改回成迭代器遍历
        for(String str : c){
            System.out.println(str);
        }
        //改回成下面的样子
        //Iterator<String> it = c.iterator();
        Iterator it = c.iterator();
        while(it.hasNext()){
            String str = (String) it.next();
            System.out.println(str);
        }
    }
}

java.util.List接口

List继承自Collection,是最常用的一类集合。

特点:可以存放重复元素且有序。List里提供了一套可以通过下标操作元素的方法。
常用实现类:
java.util.ArrayList:内部使用数组实现,查询性能更好。
java.util.LinkedList:内部使用链表实现,增删性能更好,首尾增删性能最佳。
对性能没有特别苛刻的要求下,通常使用ArrayList即可。

public class ListDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
//        List<String> list = new LinkedList<>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        System.out.println(list);
        /*
            void add(int index)//默认把该元素添加到集合后面
            void add(int index,E e)
            将给定元素插入到指定位置,后面元素往后移
         */
        //[one,two,three,six,four,five]
        list.add(3,"six");
        System.out.println(list);


        /*
            E get(int index)
            获取指定下标处对应的元素
         */
        String str = list.get(2);//与数组获取元素功能一致 String str = arr[2];
        System.out.println(str);
        //List也可以通过循环下标的方式遍历
        for(int i=0;i<list.size();i++){
            str = list.get(i);
            System.out.println(str);
        }

        /*
            E set(int index,E e)
            将给定元素设置到指定位置上,返回值为该位置原来的元素
            替换元素操作
         */
        //[one,six,three,four,five]
        String old = list.set(1,"six");//将第二个位置原来的two返回
        System.out.println(list);
        System.out.println(old);

        /*
            E remove(e)删除元素时也是删除与集合中equals比较为true的元素。
            注:对于List而言,由于可以存放重复元素,对这种情况仅会删除一次。

            E remove(int index)
            删除并返回指定位置上的元素
         */
        //[one,two,six,four,five]
        String old = list.remove(2);
        System.out.println(list);
        System.out.println(old);

        //在不创建新集合的前提下,将集合元素翻转
        for(int i=0;i<list.size()/2;i++){//i:0
//            //获取正数位置上的元素
//            String e = list.get(i);//one
//            //将正数位置上的元素来替换倒数位置上的元素
//            e = list.set(list.size()-1-i,e);//five
//            //将原倒数位置上的元素设置到正数位置上
//            list.set(i,e);
            list.set(i,list.set(list.size()-1-i,list.get(i)));
        }
        //[five,six,three,four,one]
        System.out.println(list);
        /*
           Collections是集合的工具类
           该工具类为集合提供了很多API
         */
        Collections.reverse(list);//翻转集合
        System.out.println(list);
    }
}

List集合提供获取子集的方法:
List subList(int start,int end)//获取当前集合中指定范围内的子集

对子集的操作就是对原集合对应元素的操作,对原集合进行修改,子集合会报并发修改异常,如果需要对原集合进行修改,可以重新创建一个集合,将原集合元素重新加载到新集合中,在对新集合进行操作

public class ListDemo3 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for(int i=0;i<10;i++){
            list.add(i);
        }
        System.out.println(list);
        //获取子集[3-7]
        List<Integer> subList = list.subList(3,8);
        System.out.println("sub:"+subList);
        //将子集每个元素扩大10倍
        for(int i=0;i<subList.size();i++){
            subList.set(i,subList.get(i)*10);
        }
        //[30,40,50,60,70]
        System.out.println("sub:"+subList);
        /*对子集的操作就是对原集合对应元素的操作*/
        System.out.println(list);

        //清除集合中1-8这部分元素
        list.subList(1,9).clear();
        System.out.println(list);
    }
}

集合与数组间的转化

集合转化为数组

toArray(new String[c.size()])中

①如果集合是数组类型时new String[0]性能会更好,因为该集合本身就是一个数组,直接用就可以
②如果new String[c.size()]中指定的长度小于集合长度,则以集合长度为准,返回对应长度的数组
③如果new String[c.size()]中指定的长度大于集合长度,则以指定长度为准,返回对应长度的数组,其他位置以默认值填充

/**
 * 集合转换为数组
 * Collection定义了方法toArray可以将一个集合转换为一个数组
 */
public class CollectionToArrayDemo {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("one");
        c.add("two");
        c.add("three");
        c.add("four");
        c.add("five");
        System.out.println(c);
//        Object[] array = c.toArray();
        String[] array = c.toArray(new String[c.size()]);
        /*c.toArray(new String[c.size()])中如果集合是数组类型时new String[0]性能会更好,因为该集合本身就是一个数组,之间用就可以
        如果new String[c.size()]中指定的长度小于集合长度,则以集合长度为准,返回对应长度的数组
        如果new String[c.size()]中指定的长度大于集合长度,则以指定长度为准,返回对应长度的数组,其他位置以默认值填充*/
        System.out.println(array.length);
        System.out.println(Arrays.toString(array));
    }
}

数组只能转换为List集合

数组的工具类Arrays提供了一个静态方法asList,可以将一个数组转换为一个List集合

对该集合的操作就是对原数组对应的操作,但是对该数组的操作不会影响该集合

由于数组是定长的,因此对集合增(add)删(remove)元素会导致对数组进行同等操作,这时会抛出异常:UnsupportedOperationException

如果有增删需求,则需要另外创建一个集合,并先将数组转换的集合内容导入后方可进行。

public class ArrayToListDemo {
    public static void main(String[] args) {
        String[] array = {"one","two","three","four","five"};
        System.out.println("Array:"+Arrays.toString(array));
        List<String> list = Arrays.asList(array);
        System.out.println("List:"+list);
        //对该集合的操作就是对原数组对应的操作
        list.set(1,"six");
        System.out.println("List:"+list);
        System.out.println("Array:"+Arrays.toString(array));
          //如果有增删需求,则需要另外创建一个集合,并先将数组转换的集合内容导入后方可进行。
//        List<String> list2 = new ArrayList<>();
//        list2.addAll(list);
        /*
            所有集合都支持一个参数为Collection的构造器,目标是在创建当前集合
            的同时包含给定集合中的所有元素,注意list类型的参数给set类型时,可能会导致丢失部分数据
         */
        List<String> list2 = new ArrayList<>(list);

        System.out.println("list2:"+list2);
        list2.add("seven");
        System.out.println("list2:"+list2);
    }
}

List集合的排序

集合的工具类java.util.Collections提供了一个静态方法sort,可以对List集合进行自然排序

①Collections.sort(List list)在排序List集合时要求集合元素必须实现了,Comparable接口。实现了该接口的类必须重写一个方法compareTo用与定义比较大小的规则,从而进行元素间的比较后排序。否则编译不通过。

侵入性:
当我们调用某个API时,其反过来要求我们为其修改其他额外的代码,这种现象就成为侵入性。侵入性不利于程序后期的维护,尽可能避免。
②sort(list,com)重载方法com是定义的比较规则(推荐使用)

public class SortListDemo2 {
    public static void main(String[] args) {
        //①实现Comparable接口,可以直接进行排序
        List<Integer> list1 = new ArrayList<>();
        Random random = new Random();
        for(int i=0;i<10;i++){
            list1.add(random.nextInt(100));
        }
        System.out.println(list1);
        Collections.sort(list1);
        System.out.println(list1);

        //②sort的重载方法自定义排序方法
        List<Point> list2 = new ArrayList<>();
        list2.add(new Point(1,2));
        list2.add(new Point(97,88));
        list2.add(new Point(7,6));
        System.out.println(list2);
//        Collections.sort(list2);
        Collections.sort(list2,new Comparator<Point>() {
            public int compare(Point o1, Point o2) {
            /**
             * 实现比较器接口后必须重写方法compare.
             * 该方法用来定义参数o1与参数o2的比较大小规则
             * 返回值用来表示o1与o2的大小关系
             */
                int len1 = o1.getX() * o1.getX() + o1.getY() * o1.getY();
                int len2 = o2.getX() * o2.getX() + o2.getY() * o2.getY();
                return len1-len2;
            }
        });
        System.out.println(list2);

        //③字符串排序
        List<String> list = new ArrayList<>();
        list.add("侠侣");
        list.add("雕");
        list.add("传奇故事");
        System.out.println(list);
//        Collections.sort(list);字符串默认按照Unicode进行排序
        //定义一个比较器,按照字多字少排序
        Collections.sort(list,(o1,o2)->o1.length()-o2.length());
//        Collections.sort(list, Comparator.comparingInt(String::length));
    }
}


java.util.Map接口

Map体现的结构是一个多行两列的表格,其中左列称为"key",右列称为"value"
Map总是以key-value对的形式保存一组数据。并且可以根据key获取对应的value。
Map有一个要求,key不允许重复(equals比较)
常用实现类:
java.util.HashMap,我们称它为"散列表"。当今查询速度最快的数据结构。

map的常用API:

public class MapDemo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        /*
            V put(K k,V v)
            向当前Map中保存一组键值对
         */
        map.put("语文",99);
        //如果Map的value是包装类类型,获取时不要用基本类型接收,避免自动拆箱引发空指针
        Integer value = map.put("数学",98);//key不存在时,put方法返回值为null
        System.out.println("value:"+value);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",99);
        System.out.println(map);

        value = map.put("数学",77);//key已经存在则替换value,返回值为key原来对应的value
        System.out.println("value:"+value);
        System.out.println(map);

        /*
            V get(Object key)
            根据给定的key获取对应的value,如果给定的key不存在,则返回值为null
         */
        value = map.get("语文");
        System.out.println("语文:"+value);
        value = map.get("体育");
        System.out.println("体育:"+value);

        //返回当前Map中的元素个数
        int size = map.size();
        System.out.println("size:"+size);

        /*
            删除给定的key对应的这组键值对,返回值为这个key对应的value
         */
        value = map.remove("数学");
        System.out.println(map);
        System.out.println("value:"+value);

        //可以分别判定Map是否包含给定的key或value。判定依据仍然是equals方法。
        boolean ck = map.containsKey("英语");
        System.out.println("包含key:"+ck);
        boolean cv = map.containsValue(97);
        System.out.println("包含value:"+cv);
        boolean n = map.isEmpty();
        System.out.println("map是否为空集合:"+n);
        map.clear();
        System.out.println(map);
    }
}

Map的遍历

Map支持三种遍历方式:
 * 1:单独遍历key
 * 2:遍历每一组键值对
 * 3:单独遍历value(这个操作不常用)
 

public class MapDemo2 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("语文",99);
        map.put("数学",98);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",99);
        System.out.println(map);
        /*
            Set keySet()
            将当前Map中所有的key以一个Set集合形式返回。
         */
        Set<String> keySet = map.keySet();
        for(String key : keySet){
            System.out.println("key:"+key);
        }

        /*
            遍历每一组键值对
            Set entrySet()
            将当前Map中每一组键值对以Entry实例形式表示并存入集合后返将其返回。
            java.util.Map.Entry它的每一个实例用于表示一组键值对
         */
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        for(Map.Entry<String,Integer> e : entrySet){
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key+":"+value);
        }
        /*
            Collection values()
            将所有的value以一个集合的形式返回。
         */
        Collection<Integer> values = map.values();
        for(Integer value : values){
            System.out.println("value:"+value);
        }
        /*
            JDK8之后集合和Map都支持了基于lambda表达式形式遍历。
         */
        //Map会将每一组键值对作为参数传给lambda表达式
        map.forEach(
                (k,v)-> System.out.println(k+":"+v)
        );

        Collection<String> c = new ArrayList<>();
        c.add("one");
        c.add("two");
        c.add("three");
        c.add("four");
        c.add("five");
//        c.forEach(
//                e->System.out.println(e)
//        );
        c.forEach(
                System.out::println
        );
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值