集合为什么使用集合 变量只能存一个数据,数组可以存储很多数据,但是长度固定。而集合可以自动扩容。 集合和数组的比较集合和数组都是容器,都可以存储很多数据: 1.数组长度是固定的,集合可以自动扩容 2.数组可以存储基本,引用数据类型;集合只能存储引用类型 3.集合底层有复杂的数据结构支持,效率上不如数组 集合树接口,实现类(图) Collection接口,Map接口 Collection接口—List接口Collection接口:可以重复,但是无序 | List接口:可以重复,有序,线性排序 | 实现类ArrayList、Vactor、LinkedList Collection 示例代码//util:工具类,集合的工具包
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.sql.rowset.Predicate;
/** Collection 功能 常用方法 */
public class TestCollection {
public static void main(String[] args) {
//多态形式:屏蔽继承者功能
//泛型:限制类型
Collection <String> c = new ArrayList<>();
//判断集合是否为空
System.out.println(c.isEmpty());
//数据存储成功,返回值为true
c.add("abc");
c.add("aa");
System.out.println(c);
System.out.println(c.toString());
//判断集合是否为空
System.out.println(c.isEmpty());
//集合中存储元素的个数
System.out.println(c.size());
//添加
Collection <String> cnew = new ArrayList<>();
cnew.add("fff");
cnew.add("bbb");
cnew.add("zzz");
cnew.add("fff");
//把参数集合中的所有元素添加到当前c集合,只要当前集合发生了改变,返回就是true
c.addAll(cnew);
System.out.println(c);
//删除 参数指定对象
c.remove("aa");
System.out.println(c);
//删除指定参数集合中的所有元素
c.removeAll(cnew);
System.out.println(c);
c.add("eee");
c.add("hello");
c.add("fff");
System.out.println(c);
// 按照指定条件删除
// 《一》
/* c.removeIf(new Predicate)<String>(){
// 集合元素
@Override
public boolean test (String t){
//删除长度为3的元素删除
return t.length() == 3;
}
});*/
//《二》
c.removeIf(t -> { return t.length() == 3;});
System.out.println(c);
//返回参数元素在集合中是否存在,存在则返回true
System.out.println(c.contains("cc"));
//返回指定参数集合中的所有元素在当前集合c中是否包含
System.out.println(c.containsAll(cnew));
//创建一个集合
//把数组转换成集合:这里把字符串数组转换成集合:
//List类型的 类ArrayList是Arrays的内部类,此类不允许修改,只能查看
List<String> list = Arrays.asList(new String [] {"bb","cc"});
//把集合转成Object类型的数组
System.out.println(c);
Object [] obj = c.toArray();
System.out.println(Arrays.toString(obj));
//
obj = c.toArray(new Object[10]);
//空的用null
System.out.println(Arrays.toString(obj));
// 给0 可以扩容
obj = c.toArray(new Object[0]);
System.out.println(Arrays.toString(obj));
//把集合转换成指定的类型
String [] str = c.toArray(new String[10]);
System.out.println(Arrays.toString(str));
//清空集合中的所有元素
c.clear();
System.out.println(c.isEmpty());
}
}
List示例代码
import java.util.ArrayList;
import java.util.List;
/**List */
public class TestList {
public static void main(String[] args) {
List<String > list = new ArrayList<>();
list.add("aa");//0
list.add("cc");
//指定向那个位置添加元素
list.add(1,"bb");
System.out.println(list);
//获得参数位置的元素
System.out.println(list.get(2));
//用第二个参数的元素 修改替换索引位置的元素
list.set(1, "yyy");
System.out.println(list);
//
list.add("aa");
list.add("aa");
System.out.println(list);
//返回参数袁术在集合中第一次出现的位置索引
System.out.println(list.indexOf("aa"));
//返回参数袁术在集合中最后一次出现的位置索引
System.out.println(list.lastIndexOf("aa"));
//【1,3)之间的元素
System.out.println(list.subList(1,3));
list.sort(null);//comparable自然排序 升序
//comparator比较器
list.sort((s1,s2) -> {return s2.compareTo(s1);});
System.out.println(list);
}
}
集合遍历和迭代器示例代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**集合遍历 */
public class TeatIterator {
public static void main(String[] args) {
//List有序,collection无序,这里用collection会出错
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
//------------遍历----------------
//1.List独特的索引:普通for循环遍历
System.out.println(list.size());
for(int i = 0; i < list.size() ; i++){
System.out.println(list.get(i));
}
//2.增强for
for(String s : list){
System.out.println(s.toString());
}
//3.集合对象的forEach方法
/* list.forEach(new Consumer<String>(){
@Override
public void accept(String t){
System.out.println(t);
}
});*/
list.forEach(t -> {System.out.println(t);});
//4.
//获得某一个集合的迭代器
Iterator<String> i = list.iterator();
/* System.out.println(i.next());
System.out.println(i.next());
i.remove();//删除最近一次访问的元素
*/ System.out.println(list);
//判断是否存在下个元素,存在返回true
while( i.hasNext() ){
//循环遍历
System.out.println(i.next());
}
//5.迭代器的forEach方法
Iterator<String> i1 = list.iterator();
i1.forEachRemaining(System.out::println);
//6.使用Stream流的方法
list.stream().forEach(System.out::println);
System.out.println("--------------list----------------");
//Iterator遍历collectorlistIterator专门为List迭代,是Iterator的子接口
//7.
ListIterator<String> li = list.listIterator();
while(li.hasNext()){
System.out.println(li.next());
li.add("hello");
}
//向上迭代
while(li.hasPrevious()){
System.out.println(li.previous());
}
}
}
collection接口-Set接口
collection接口:可以重复,但是无序
|
Set接口:不重复,无序。
HashSet -> LinkedHashSet
|
SortedSet 接口:排了序的
|
NavigableSet接口
|
TreeSet类
HashSet示例代码:
import java.util.HashSet;
import java.util.Set;
class Employee{
private int no;
private String name;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(int no, String name) {
super();
this.no = no;
this.name = name;
}
public Employee() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return name + ","+ no;
}
@Override
public int hashCode() {
return name.hashCode() + no;
}
@Override
public boolean equals(Object obj) {
//this和obj判断
Employee emp = (Employee)obj;
return this.no == emp.no && this.name.equals(emp.name);
}
}
public class TestHashSet {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("aa");
set.add("bb");
set.add("cc");
set.add("dd");
for(String s : set){
System.out.println(s);
}
//正式因为它的数据存储结构是哈希表,在存储数据时hashcode相同且equals执行为相同时,就不会再存这个数
set.add("aa");
for(String s : set){
System.out.println(s);
}
Set<Employee> emps = new HashSet<>();
//只要两个对象的属性值都相同,那么就是同一个对象
Employee zhangsan = new Employee(22,"张三");
Employee lisi = new Employee(22,"张三");
Employee wangwu = new Employee(33,"王五");
emps.add(zhangsan );
emps.add(lisi);
emps.add(wangwu);
for(Employee e : emps){
System.out.println(e);
}
}
}SortedSet-TreeSet示例代码
import java.util.SortedSet;
import java.util.TreeSet;
public class TestSortedSet {
public static void main(String[] args) {
//《一》自然排序
//SortedSet<Integer> set = new TreeSet<>();
//《二》自定义降序
SortedSet<Integer> set = new TreeSet<>((n1,n2) -> {return n2 - n1;});
set.add(22);
set.add(11);
set.add(33);
System.out.println(set);
System.out.println(set.first());
System.out.println(set.last());
//《一》
//【起始元素,终止元素)
// System.out.println(set.subSet(11,33));
}
}NavigableSet
import java.util.NavigableSet;
import java.util.TreeSet;
/** NavigableSet接口,提供了最接近匹配原则的检索元素方法 */
public class TestNavigableSet {
public static void main(String[] args) {
NavigableSet <Integer> set = new TreeSet<>();
set.add(22);
set.add(38);
set.add(39);
set.add(55);
set.add(66);
//小于等于44的最大集合元素
System.out.println(set.floor(44));
//大于等于参数44的最小集合元素
System.out.println(set.ceiling(44));
//获得降序的集合
System.out.println(set);
set.descendingSet().forEach(System.out :: println);
//降序的迭代器
set.descendingIterator().forEachRemaining(System.out::println);
//移除元素
set.pollFirst();
set.pollLast();
System.out.println(set);
}
}
Set实现类的区别- 底层数据结构是数组:遍历和随机访问快一些,添加删除效率低
ArrayList:线程是非安全的; 出现早,性能高;Collections方法包装成线程安全的使用;50%扩容 Vector:线程安全的; 出现早,性能差;100%扩容,占用空间多,效率低;
Stack栈 :效率低 - 底层数据结构是链表:遍历和随机访问慢一些,添加删除效率高
链表:存储数据元素称为节点,有序的 节点分为数据域和指针域(图)
- linked HashSet底层数据结构是哈希表hash存储唯一方式:(图) 首先对象调用hashCode()根据对象的自身特征算出一个hash值(位置值),没有冲突,可以存储,但是 遇到了哈希冲突(算出的hash值都相同),这时调用equals判断是否为同一个对象,是就存了,不是可以同一个位置链式存储。 TreeSet的底层数据于结构是二叉树树:表示一种层次关系(图) 实现类的区别:HashSet 底层是 哈希表;数据唯一存储;效率高于LinkedHashSet和TreeSet LinkedHashSet 底层是链表 哈希表;按照元素添加的顺序维护。 TreeSet 底层是二叉树;按照升序或者自己指定次序来维护次序。(自然升序)
|