学习笔记:Java集合——Collection

集合:一种用来储存数据的容器。

数组也是一种存储数据的容器,既然已经有了数据,为什么还要有集合?实际中,我们很多时候并不知道数据规模(数据的量),而数组的长度在初始化时就要给定,并且数组的长度是不可变的,那么就会出现一个问题,如果现在要将一堆数字存在数组中,那么,在数组初始化的时候,长度给多少合适?给小了,存不下,给多了,浪费资源;初次之外,一个数组中,只能存放类型相同的元素,无法存放具有映射关系的数据,如:“张三-语文-90分”。

集合类就应运而生了,主要负责保存、盛装其他数据。所有的集合都位于java.util包下

那么,集合和数组有什么区别:

①数组是定长的,既可以存放基本类型又可以存放引用类型,且存放类型一致的;

② 集合长度是可变的,只能存放引用类型(基本数据会自动装箱为包装类)

图1. 集合(部分)知识体系

Java集合框架主要有两大根接口:Collection 和 Map。这两个包含了一些子接口和实现类。

           集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map。

Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类有java.util.ArrayList和java.util.LinkedList,Set接口的主要实现类有java.util.HashSet和java.util.TreeSet。

Collection

Collection 是 List接口 和 Set接口的父接口。

不同容器的的数据结构不同,但是他们都有一些共性,抽取之后是Collection。

vector的特点是,查询快 增删慢 。但已经过时,不在过多详述。

Collection 的主要方法如下:

//创建一个集合,由于接口无法实例化,所以暂时创建一个子接口的实现类
        Collection collection = new ArrayList();

//        1. add:添加元素,返回值boolean,成功为true。
        boolean b = collection.add("张三");
        System.out.println(b);
        System.out.println("添加后的元素:" + collection);
        System.out.println("*********************");

//        2. clear:清空集合中的所有元素。集合容器本身不会改变,继续使用
        collection.clear();
        System.out.println("清空集合后" + collection);
        System.out.println("*********************");

//        3. remove:移除集合中的单个实例(参数obj),移除成功返回true
        collection.add("张三");
        collection.add("李四");
        System.out.println("移除李四前:" + collection);
        boolean b1 = collection.remove("李四");
        System.out.println(b1 + " 移除李四后: " + collection);
        System.out.println("*********************");

//        4. isEmpty: 判断当前集合是否为空
        boolean b2 = collection.isEmpty();
        System.out.println(b2 + "  "  + collection);
        System.out.println("*********************");

//        5. contains :包含某个元素,如果有返回true,区分大小写
        System.out.println("集合现有" + collection);
        boolean b3 = collection.contains("张三");
        boolean b4 = collection.contains("李四");
        System.out.println("包含张三吗?" + b3);
        System.out.println("包含李四吗?" + b4);
        System.out.println("*********************");

//        6. size:获取大小
        System.out.println("集合现有" + collection);
        System.out.println(collection.size());
        System.out.println("*********************");

//        7. toArray:集合中的元素,变成数组。集合存储的数据类型不确定,返回的数组只能是Object
        System.out.println("集合现有" + collection);
        Object[] objects = collection.toArray();


    }

迭代器

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.Iterator 。Iterator 接口也是Java集合中的一员,但它与Collection 、Map 接口有所不同,Collection 接口与Map 接口主要用于存储元素,而Iterator 主要用于迭代访问(即遍历) Collection 中的元素,因此Iterator 对象也被称为迭代器。

迭代即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个
元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业
术语称为迭代。

Iterator iterator() : 获取集合对应的迭代器,用来遍历集合中的元素的:

Iterator接口的常用方法如下:
public E next() :返回迭代的下一个元素。
public boolean hasNext() :如果仍有元素可以迭代,则返回 true。

// 使用多态方式 创建对象,因为接口不能被直接创建需要new其一个子类
Collection<String> coll = new ArrayList<String>();
// 添加元素到集合
coll.add("aaa");
coll.add("bbb");
coll.add("汪星人");
//遍历
//使用迭代器 遍历 每个集合对象都有自己的迭代器
Iterator<String> it = coll.iterator();
// 泛型指的是 迭代出 元素的数据类型
while(it.hasNext()){ //判断是否有迭代元素
    String s = it.next();//获取迭代出的元素
    System.out.println(s);
}

迭代器原理:

图2. 迭代器原理

增强for

增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

格式:  for(元素的数据类型 变量 : Collection集合or数组){   //写操作代码   }

/* 例1 */
int[] arr = {3,5,6,87};
//使用增强for遍历数组
for(int a : arr){//a代表数组中的每个元素
    System.out.println(a);
}

/* 例2 */
Collection<String> coll = new ArrayList<String>();
coll.add("小河神");
coll.add("老河神");
coll.add("神婆");
for(String s :coll){
    System.out.println(s);
}

List、Set

Map


可变参数
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格
式:

修饰符 返回值类型 方法名(参数类型... 形参名){ }
其实这个书写完全等价与

修饰符 返回值类型 方法名(参数类型[] 形参名){ }
只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。JDK1.5以后。出现了简化操作。... 用在参数上,称之为可变参数。

Collections 

java.utils.Collections 是集合工具类,用来对集合进行操作

boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
void sort(List<T> list) :将集合中元素按照默认规则排序。
void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。

//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
//排序方法
Collections.sort(list);
System.out.println(list);

Comparator比较器 

         两个对象之间比较大小,在JAVA中提供了两种比较实现的方式,一种是比较死板的采用java.lang.Comparable 接口去实现,一种是灵活的当我需要做排序的时候在去选择的java.util.Comparator 接口完成。

         我们采用的public static <T> void sort(List<T> list) 这个方法完成的排序,实际上要求了被排序的类型
需要实现Comparable接口完成比较的功能,在String类型上如下:

         public final class String implements java.io.Serializable, Comparable<String>, CharSequence {  ...  }

          那比如我想要字符串按照第一个字符降序排列,那么这样就要修改String的源代码,这是不可能的了,那么这个时候我们可以使用  public static <T> void sort(List<T> list,Comparator<? super T> ) 方法灵活的完成,这个里面就涉及到了Comparator这个接口,位于位于java.util包下,排序是comparator能实现的功能之一,该接口代表一个比较器,比较器具有可比性!顾名思义就是做排序的,通俗地讲需要比较两个对象谁排在前谁排在后,那么比较的方法就是: 

          public int compare(String o1, String o2) :比较其两个参数的顺序。
两个对象比较的结果有三种:大于,等于,小于。
如果要按照升序排序, 则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数) 如果要按照
降序排序 则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)

ArrayList<String> list = new ArrayList<String>();
list.add("cba");
list.add("aba");
list.add("sba");
list.add("nba");
//排序方法 按照第一个单词的降序
Collections.sort(list, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o2.charAt(0) ‐ o1.charAt(0);
        }
});
System.out.println(list);

         Comparable和Comparator两个接口的区别
         Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
         Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。

关于比较器,还可以参考文章:

译文链接:http://www.codeceo.com/article/java-objects-sort.html
英文原文:How To Sort Objects In Java
翻译作者:码农网 – 小峰


JDK9对集合添加的优化 

Java 9,添加了几种集合工厂方法,更方便创建少量元素的集合、map实例。新的List、Set、Map的静态工厂方法可以更方便地创建集合的不可变实例。
例子:

Set<String> str1=Set.of("a","b","c");
//str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
System.out.println(str1);
Map<String,Integer> str2=Map.of("a",1,"b",2);
System.out.println(str2);
List<String> str3=List.of("a","b");
System.out.println(str3);

1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如
HashSet,ArrayList等待;
2:返回的集合是不可变的;

猜你喜欢

转载自blog.csdn.net/weixin_38816084/article/details/82670977
今日推荐