带你了解Java高级编程-----集合
Posted 符工爱奇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你了解Java高级编程-----集合相关的知识,希望对你有一定的参考价值。
文章目录
一、Java集合的整体介绍
- Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的
关联数组。很好的应对了数组array的弊端。 - 使用的场景:
①android客户端 ②服务器 ③端数据库
二、Collection接口
Collection接口:单列数据,定义了存取一组对象的方法的集合。
- Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法 既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
- JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List) 实现。
- Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理; 但可以增加泛型,来实现Java 集合记住容器中对象的数据类型。
1、Collection接口方法
方法 | 方法说明 |
---|---|
add(Object obj) | 添加元素 |
addAll(Collection coll) | 添加整个集合 |
int size() | 获取有效元素的个数 |
void clear() | 清空集合 |
boolean isEmpty() | 是否是空集合 |
boolean contains(Object obj) | 是否包含某个元素,是通过元素的equals方法来判断是否是同一个对象 |
boolean containsAll(Collection c) | 是否包含某个元素, 也是调用元素的equals方法来拿两个集合的元素挨个比较。 |
boolean remove(Object obj) | 通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素 |
boolean removeAll(Collection coll) | 删除集合中所有的此元素(取当前集合的差集) |
boolean retainAll(Collection c) | 取两个集合中的交集(把交集的结果存在当前集合中,不影响c) |
boolean equals(Object obj) | 判断集合是否相等 |
Object[] toArray() | 转成对象数组 |
hashCode() | 获取集合对象的哈希值 |
iterator() | 返回迭代器对象,用于集合遍历 |
package Collection接口;
import org.junit.Test;
import java.util.*;
public class CollectionTest {
@Test
public void test1(){
Collection coll= new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Jerry"));
Person p = new Person("Tom",15);
coll.add(p);
coll.add(true);
// 1.contains(object obj):判断当前集合中是否包含obj
// 在判断时会调用obj对象所在类的equals()
boolean contains = coll.contains(123);
System.out.println(contains); //true
System.out.println(coll.contains(new String("Jerry"))); //true
System.out.println(coll.contains(new Person("Tom", 15))); //false ---> true 进行重写equals方法
System.out.println(coll.contains(p)); //true
//2.containsAll(Collection coll1) : 判断形参coll1中的所有元素是否都存在于当前集合中
Collection coll1 = Arrays.asList(123,456);
System.out.println(coll.containsAll(coll1)); //true
}
@Test
public void test2(){
//3.remove(Object obj):
Collection coll= new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Jerry"));
Person p = new Person("Tom",15);
coll.add(p);
coll.add(false);
coll.remove(1234);
System.out.println(coll); //[123, 456, Jerry, Collection接口.For_Iterator.Person{name='Tom', age=15}, false]
coll.remove(new Person("Tom",15));
System.out.println(coll); //[123, 456, Jerry, false]
//4.removeAll(Collection coll1):从当前的集合中移除从从coll1中的所有元素
Collection coll1 = Arrays.asList(123,456);
coll.removeAll(coll1);
System.out.println(coll); //[Jerry, false]
}
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Jerry"));
Person p = new Person("Tom",15);
coll.add(p);
coll.add(false);
/* // 5.retainAll(Collection coll): 交集 :获取当前集合和从coll1集合的交集,并返回给当前集合
Collection coll1 = Arrays.asList(123,456,789);
coll.retainAll(coll1);
System.out.println(coll); //[123, 456]*/
//6.equals(Object obj) :
Collection coll1 = new ArrayList(); //Array是有序的,如果add的顺序不同,依然输出false
coll1.add(123);
coll1.add(456);
coll1.add(new String("Jerry"));
coll1.add(new Person("Tom",15));
coll1.add(false);
System.out.println(coll.equals(coll1)); //true
}
@Test
public void test4(){
Collection coll= new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Jerry"));
Person p = new Person("Tom",15);
coll.add(p);
coll.add(false);
// 7.hasCode() : 返回当前对象的哈希值
System.out.println(hashCode());
//8.集合 --> 数组 :toArray()
Object[] arr = coll.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//拓展 :数组 --> 集合 【注意asList要用包装类,否则将视为一个元素】
List<String> strings = Arrays.asList(new String[]{"AA", "BB", "CC", "DD"});
System.out.println(strings); //[AA, BB, CC, DD]
List ints = Arrays.asList(new int[]{12, 34, 56});
System.out.println(ints.size()); // 1
List ints1 = Arrays.asList(new Integer[]{12, 34, 56});
System.out.println(ints1.size()); // 3
// 9.iterator(): 返回Iterator()接口的实例,用于遍历集合元素。放在IteratorTest.java 中测试
}
}
class Person{
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public String toString() {
return "Collection接口.For_Iterator.Person{" +
"name='" + name + '\\'' +
", age=" + age +
'}';
}
}
2、Collection子接口一:List
List:元素有序,可重复的集合。
鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组
List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。
List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
- JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。
List接口的主要方法:
【除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法】
方法 | 方法说明 |
---|---|
void add(int index, Object ele) | 在index位置插入ele元素 |
boolean addAll(int index, Collection eles) | 从index位置开始将eles中的所有元素添加进来 |
Object get(int index) | 获取指定index位置的元素 |
int indexOf(Object obj) | 返回obj在集合中首次出现的位置 |
int lastIndexOf(Object obj) | 返回obj在当前集合中末次出现的位置 |
Object remove(int index) | 移除指定index位置的元素,并返回此元素 |
Object set(int index, Object ele) | 设置指定index位置的元素为ele |
List subList(int fromIndex, int toIndex) | 返回从fromIndex到toIndex位置的子集合 |
①ArrayList ⭐
作为List 接口的主要实现类;线程不安全,效率高
- ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
- ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
package List接口;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 常用方法总结:
* 增:add(Object obj)
* 删:remove(int index) / remove(Object obj
* 改:set(int index,Object ele)
* 查:get(int index,Object ele)
* 插:add(int index,Object obj)
* 长度:size()
*/
public class ListTest {
@Test
public void test1(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom",12));
list.add(false);
System.out.println(list); //[123, 456, AA, For_Iterator.Person{name='Tom', age=12}, false]
//1. void add (int index, Object ele) : 在index位置插入ele元素
list.add(1,"BB");
System.out.println(list); //[123, BB, 456, AA, For_Iterator.Person{name='Tom', age=12}, false]
List list1 = Arrays.asList(1,2,3);
//list.addAll(list1); //[123, BB, 456, AA, For_Iterator.Person{name='Tom', age=12}, false, 1, 2, 3]
list.add(list1); //[123, BB, 456, AA, For_Iterator.Person{name='Tom', age=12}, false, [1, 2, 3]]
System.out.println(list);
//2.Object get(int index) : 获取指定index位置的元素
System.out.println(list.get(2)); // 456
}
@Test
public void test2(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom",12));
list.add(false);
//3.int index(Object obj) : 返回obj在集合中首次出现的位置
int index = list.indexOf(123);
System.out.println(index); // 0
//4.int lastIndexOf(Object obj) : 返回obj在集合中末次出现的位置
int lastIndexOf = list.lastIndexOf(456);
System.out.println(lastIndexOf); // 1
//5.Object remove(int index) : 移除指定index位置的元素,并返回此元素
Object obj = list.remove(0);
System.out.println(obj); // 123
System.out.println(list); // [456, AA, For_Iterator.Person{name='Tom', age=12}, false]
//6.Object set(int index,Object ele) : 设置指定index位置的元素ele
list.set(0,123);
System.out.println(list); //[123, AA, For_Iterator.Person{name='Tom', age=12}, false]
//7.list subList(int formIndex,int toIndex) : 返回从fromIndex到toIndex位置的左闭右开区间
List subList = list.subList(2, 4);
System.out.println(subList); //[For_Iterator.Person{name='Tom', age=12}, false]
System.out.println(list); //[123, AA, For_Iterator.Person{name='Tom', age=12}, false]
}
}
②LinkedList
对于频繁的插入、删除操作、使用此类的效率比ArrayList搞;底层使用的是双向列表存储
链表(Linkedlist)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
- 一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
- 一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。
【使用方式于ArrayList基本相同,在此就不进行代码上的重复】
③Vector
作为List 接口古老实现类;线程安全,效率低;
面试题
ArrayList和LinkedList的异同?
二者都线程不安全,相对线程安全的Vector,执行效率高。
此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。ArrayList和Vector的区别?
Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类。因此开销就比ArrayList要大,访问要慢。正常情况下,大多数的Java程序员使用ArrayList而不是Vector,因为同步完全可以由程序员自己来控制。Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。
3、Collection子接口二:Set
Set:元素无序,不可重复的集合。 储存无序的 ≠ 随机性,根据数据的hash值顺序进行添加
- Set接口是Collection的子接口,set接口没有提供额外的方法。
- Set集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。
- Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法。
①HashSet
作为Set接口的主要实现类 ;线程不安全 ,可以存储null值
LinkHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历
import org.junit.Test;
import java.util.*;
public class SetTest {
/*
Set接口 :1. 储存无序的 ≠ 随机性,根据数据的hash值顺序进行添加
2. 不可重复的数据
*/
@Test
public void HashTest(){
Set set = new HashSet();
set.add(456);
set.add(123);
set.add(123);
set.add("AA");
set.add(new Person("Tom",12));
//set.add(new User("Tom",12));
set.add("cc");
set.add(false);
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.print(iterator.next() + " ");
//AA cc Collection接口.For_Iterator.Person{name='Tom', age=12} false 456 123
}
}
@Test
public void LinkedHashTest(){
/*
LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前后两个数据。
优点 :对于频繁的遍历操作,LinkedHashSet的效率要高于HashSet
*/
Set set = new LinkedHashSet();
set.add(456);
set.add(123);
set.add(123);
set.add("AA");
set.add(new Person("Tom",12));
set.add("cc");
以上是关于带你了解Java高级编程-----集合的主要内容,如果未能解决你的问题,请参考以下文章