java自学-集合cloection和泛型

Collection 

数组一旦初始化后,长度就确定了,存储数据对象不能达到动态扩展,其次数组存储元素不便于对数组进行添加修改删除操作,而且数组可以存储重复元素。面对这些问题,集合的作用显现出来了。集合分为CollectionMap两种体系。。其中collection中的元素是一个value值,map中的元素是key:value形式的。collection来源于Java.util包,字面意思就是容器。
Collection的继承体系:
List:

1. 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
常用方法:
public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素
例子:
public class ListDemo {
public static void main(String[] args) {
// 创建List集合对象
List<String> list = new ArrayList<String>();
// 往 尾部添加 指定元素
list.add("图图");
list.add("小美");
list.add("不高兴");
System.out.println(list);
// add(int index,String s) 往指定位置添加
list.add(1,"没头脑");
System.out.println(list);
// String remove(int index) 删除指定位置元素 返回被删除元素
// 删除索引位置为2的元素
System.out.println("删除索引位置为2的元素");
System.out.println(list.remove(2));
System.out.println(list);
// String set(int index,String s)
// 在指定位置 进行 元素替代(改)
// 修改指定位置元素
list.set(0, "三毛");
System.out.println(list);
// String get(int index) 获取指定位置元素
// 跟size() 方法一起用 来 遍历的
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
//还可以使用增强for
for (String string : list) {
System.out.println(string);
}
}
}

 

List的常用子类:

ArrayList

java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList 是最常用的集合。

LinkedList

java.util.LinkedList 集合数据存储的结构是链表结构。方便元素添加、删除的集合。
Vector(实际开发不常用,面试时会和ArrayList做对比)
Vector是【同步】操作
ArrayList是【异步】操作


Set:

java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不
同的是, Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

Set 的常用子类:
HashSet

java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。 HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性的方式依赖于: hashCode 与 equals 方法。

LinkedHashSet(有序)

 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构,元素是有序的。

TreeSet:不可重复,没有索引
底层就是红黑树,可以对集合中的元素按照元素的内容实现排序
去重原理:基于compareTo的返回值来实现去重,与hashCode和equals方法无关,返回值为0,就认为是重复元素,不再添加

举例:

public class Person implements Comparable<Person>{
                    private String name;
                    private int age;

                    ......
                    
                    @Override
                    public int compareTo(Person o) {
                        int i = o.age - this.age;
                        if (i == 0){
                            return this.name.hashCode() - o.name.hashCode();
                        }
                        return i;
                    }
                }
                
                =====================
                TreeSet<Person> set = new TreeSet<>();
                Person p1 = new Person("小美女1",18);
                Person p4 = new Person("小美女4",18);
                Person p3 = new Person("小美女3",24);
                Person p2 = new Person("小美女2",74);
                Person p5 = new Person("小美女5",60);
        
                set.add(p1);
                set.add(p2);
                set.add(p3);
                set.add(p4);
                set.add(p5);
                
                System.out.println(set);

 

Collection的常用方法:
public boolean add(E e): 把给定的对象添加到当前集合中,添加成功返回true,否则返回false 。
public void clear() :清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除,有并删除成功返回true,没有或者删除失败返回false。
public boolean contains(E e): 判断当前集合中是否包含给定的对象,包含返回true,否则返回false。
public boolean isEmpty(): 判断当前集合是否为空,为空返回true,否则返回false。
public int size(): 返回集合中元素的个数。
public Object[] toArray(): 把集合中的元素,存储到数组中。
public T[] toArray(T[] arr) :把集合转成指定类型的数组
如: 

Collection<String> coll = new ArrayList<>();
String[] arr = coll.toArray(new String[0]); -- 转成String类型数组
Object[] arr2 = coll.toArray(); -- 转成Object类型数组

Collection的遍历方式:
方式一:转成数组后,通过角标方式遍历
方式二:通过集合的特有方式--迭代器(Iterator)
Iterator常用方法:
boolean hasNext(); -- 判断集合中是否有下一个元素
E next(); -- 如果有下一个元素,该方法取出该元素
remove(); -- 如果有下一个元素,该方法删除该元素
举例:

Collection coll = new ArrayList();
Iterator it = coll.iterator();
while(it.hasNext()){
it.next();
}

方式三:增强for循环(内部用的就是Iterator)
举例:

for(int i=0;i<xx;i++){ -- 当需要修改原本容器中的值时,使用普通for循环

}

for(数据类型 变量名 :集合){ -- 当仅仅只是遍历容器取值时,使用增强for循环最方便

}

List<String> list;

for(String s : list){

}

注意:在迭代过程中,是不允许使用【原来集合】对集合中的元素做删除操作的,否则会出现【并发修改异常-ConcurrentModificationException】
假如有删除的需求,怎么做?
① 使用迭代器对象的remove方法实现删除操作 -- 要求必须有迭代器对象
② 将需要删除的元素,保存在另一个集合中, 等遍历结束后,调用【原来集合】的removeAll方法删除

Collections
java.utils.Collections 是集合工具类,用来对集合进行操作。部分方法如下:
public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
举例:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
//排序方法
Collections.sort(list);
System.out.println(list);
}
}
结果:
[5, 222, 1, 2]
[1, 2, 5, 222]
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返回(负数)

举例:

public class CollectionsDemo3 {
public static void main(String[] args) {
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提供排序。

泛型:引用数据类型的占位符,仅限于定义类或者功能时使用
注意:在使用类或者功能时,要确定具体的数据类型,这个时候就不能在使用泛型了
举例:

class PageBean<T>{
List<T> list;
}

泛型可以定义在类上,也可以定义在方法上,那么这两者的区别是什么呢?
区别①:
定义在类上的泛型,作用范围为整个类有效,包括变量包括方法
定义在方法上的泛型,只对当前方法有效,对其他方法和变量无效
区别②:
对于静态方法中的泛型声明,只能定义在方法上
如:

/**
* 定义一个方法,将某个数据类型的集合转成对应数据类型的数组
*/
public class CollectionUtils {

public static <T> T[] toArray(List<T> list,T[] arr){

for (int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}

return arr;
}
}


通配符?:泛型的占位符,在使用泛型类时,如果不能确定具体的数据类型,使用?占位
? extends T: 只能是T类型或者T的子类型,上限已经被限制
? super T:只能是T类型或者T类型的父类型,下限已经被限制

posted @ 2020-06-16 15:51  自习小夫子  阅读(249)  评论(0编辑  收藏  举报