Java基础-14
来源:互联网 发布:海岛奇兵科技升级数据 编辑:程序博客网 时间:2024/06/14 00:08
Java基础-集合
集合入门
1、集合框架(体系概述)
集合类Collection:
为什么出现集合类?面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象进行操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可以变得,数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点。
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同,这个存储方式称之为:数据结构。
集合图:
Collection类属于java.util.*;包中
2、集合框架(共性方法)
import java.util.*;class CollectionDemo{ public static void main(String[]args) { method_1(); method_2(); } public static void method_1() { //创建一个集合容器,使用Collection接口的子类ArrayList类 ArrayList al = new ArrayList(); //添加元素到容器al中。 al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); //打印容器中的元素 System.out.println("al中有:"+al); //获取个数,集合长度。 System.out.println("al.size :"+al.size()); //删除元素 al.remove(1); System.out.println("删除java03是否成功?"+al.remove("java03")); //清空集合 al.clear(); System.out.println("清空集合后al中有:"+al); //判断元素 System.out.println("al中是否存在java03?"+al.contains("java03")); System.out.println("al是否为空?"+al.isEmpty()); } public static void method_2() { ArrayList al1 = new ArrayList(); ArrayList al2 = new ArrayList(); al2.add("java01"); al2.add("java02"); al2.add("java03"); al2.add("java04"); al1.add("java01"); al1.add("java02"); al1.add("java05"); al1.add("java06"); //取交集 al1.retainAll(al2); System.out.println("al1取了al2的交集后的结果是"+al1); //去掉相同的子集 al2.removeAll(al1); System.out.println("al2被去掉了al1中相同的子集后的结果是:"+al2); }}
输出结果:
al中有:[java01, java02, java03, java04]al.size :4删除java03是否成功?true清空集合后al中有:[]al中是否存在java03?falseal是否为空?trueal1取了al2的交集后的结果是[java01, java02]al2被去掉了al1中相同的子集后的结果是:[java03, java04]
图:
3、集合框架(迭代器)
什么是迭代器?
其实就是集合取出元素方式。就把取出方式定义在集合内部,这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成内部类,而每一个容器的数据结构不同,所以取出的动作细节不一样,但是都有共性内容:判断和取出,那么可以将共性抽取,那么这些内部类都符合一个规则,该规则就是Iterator。
如何获取集合的取出对象呢?
通过一个对外提供的方式:iterator();
import java.util.*;class CollectionDemo{ public static void main(String[]args) { method_get(); } public static void method_get() { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); Iterator it = al.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //另一种使用迭代器的方法,可以更省资源 System.out.println(); for(Iterator it1 = al.iterator();it1.hasNext();)//当for循环完毕,Iterator it1 = al.iterator()语句释放 { System.out.println(it1.next()); } }}
输出结果:
java01java02java03java04java01java02java03java04
4、集合框架(List集合共性方法)
Collection
|--List:元素是有序的,同时元素可以重复,因为该集合体系有索引
|--Set:元素是无序的,不能重复。
List(接口):特有方法:凡是可以操作角标的方法都是该体系特有方法。
增:
void add(int index,E element);//将指定的元素插入此列表中的指定位置。boolean addAll(int index,Collection c);// 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
删
E remove(int index);// 移除此列表中指定位置上的元素。
改
E set(int index, E element);//用指定的元素替代此列表中指定位置上的元素。
查
E get(int index);//返回此列表中指定位置上的元素。List<E> subList(int fromIndex , int toIndex);//返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。ListIterator<E> listIterator();//返回此列表元素的列表迭代器(按适当顺序)。
演示代码:
import java.util.*;class ListDemo{ public static void main(String[]args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); System.out.println("原集合al:"+al); //在指定的位置添加元素: al.add(1,"java09"); System.out.println("al.add(1,\"java09\"):"+al); //删除指定位置元素 al.remove(2); System.out.println("al.remove(2):"+al); //修改元素 al.set(1,"java0001"); System.out.println("al.set(1,\"java0001\"):"+al); //通过角标获取元素 System.out.println("al.get(1):"+al.get(1)); //获取所有元素 //方式1 for(int x = 0;x<al.size();x++) { System.out.println(al.get(x)); } //方式2 System.out.println(); Iterator it = al.iterator(); while(it.hasNext()) { System.out.println(it.next()); } }}
输出结果:
原集合al:[java01, java02, java03, java04]al.add(1,"java09"):[java01, java09, java02, java03, java04]al.remove(2):[java01, java09, java03, java04]al.set(1,"java0001"):[java01, java0001, java03, java04]al.get(1):java0001java01java0001java03java04java01java0001java03java04
5、集合框架(ListIterator)
演示代码:
import java.util.*;class ListDemo{ public static void main(String[]args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); System.out.println("原集合al:"+al); //通过indexOf获取对象的位置 System.out.println("java02的index是:"+al.indexOf("java02")); //获取子对象集 List sub = al.subList(1,3); System.out.println("下标1到2的子对象集是:"+sub); }}
输出结果:
原集合al:[java01, java02, java03, java04]java02的index是:1下标1到2的子对象集是:[java02, java03]
演示代码:下面这段代码会引起异常,原因是并发操作。
import java.util.*;class ListDemo{ public static void main(String[]args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); System.out.println("原集合al:"+al); Iterator it = al.iterator(); //下面代码目的是在迭代过程中,使用集合的方法来对it对象中的元素进行添加或删除元素。 while(it.hasNext()) { Object obj = it.next(); if(obj.equals("java02")) { al.add("java09");//这是集合的方法,会引起并发异常 } System.out.println("obj"+obj); } }}
输出结果:
原集合al:[java01, java02, java03, java04]objjava01objjava02Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886) at java.util.ArrayList$Itr.next(ArrayList.java:836) at day09.ListDemo.main(Outer.java:18)
以上代码引发了问题,就是如何在迭代器中进行元素的添加或删除呢?
List集合特有的迭代器,ListIterator是Iterator的子接口。在使用Iterator中的迭代器迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。所以,在迭代,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出和删除的操作。如果想要其他的操作如:添加、修改等,就需要使用其子接口:ListIterator,该接口只能通过ListIterator方法获取
改进代码如下:
import java.util.*;class ListDemo{ public static void main(String[]args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); System.out.println("原集合al:"+al); ListIterator li = al.listIterator(); while(li.hasNext()) { Object obj = li.next(); //添加 if(obj.equals("java02")) { li.add("java09"); } //修改 if(obj.equals("java03")) { li.set("java003"); } } System.out.println("修改后al:"+al); }}
输出结果:
原集合al:[java01, java02, java03, java04]修改后al:[java01, java02, java09, java003, java04]
6、集合框架(List集合具体对象的特点)
List
|--ArrayList:底层的数据结构使用的是数组结构,特点:查询快,但增删稍慢,线程不同步。
|--LinkedList:底层使用链表数据结构,增删速度快,查询慢。
|--Vector:底层是数组数据结构,被ArrayList替代了,但它们间不同的是Vector线程同步。
7、集合框架(Vector中的枚举)
import java.util.*;class VectorDemo{ public static void main(String[]args) { Vector v = new Vector(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en = v.elements(); while(en.hasMoreElements()) { System.out.println(en.nextElement()); } }}
输出结果:
java01java02java03java04
枚举就是Vector特有的取出方式。
发现枚举和迭代器很像,其实枚举和迭代是一样的,因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举就很少被人使用了。
8、集合框架(LinkedList)
LinkedList特有方法:
void addFirst(E e);//将指定元素插入此列表的开头。void addLast(E e);// 将指定元素添加到此列表的结尾。boolean offerFirst(E e );//在此列表的开头插入指定的元素。JDK1.6版本boolean offerLast(E e);//在此列表末尾插入指定的元素。JDK1.6版本E getFirst();//返回此列表的第一个元素。E getLast();// 返回此列表的最后一个元素。E peekFirst();//获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。JDK1.6版本E peekLast();//获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。JDK1.6版本E removeFirst();//移除并返回此列表的第一个元素。E removeLast();//移除并返回此列表的最后一个元素。E pollFirst();//获取并移除此列表的第一个元素;如果此列表为空,则返回 null。JDK1.6版本E pollLast();//获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。JDK1.6版本
因为如果集合中没有元素,会出现NoSuchElementException,在JDK1.6出现了替代方法,以上JDK1.6版本的功能,这些方法不会返回异常而是null。
9、集合框架(LinkedList练习)
使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈:先进后出,如同一个杯子。 队列:先进先出,如同一个水管。 测试代码:
import java.util.*;class DuiLie{ private LinkedList link; DuiLie() { link = new LinkedList(); } public void bianli() { for(int x = 0;x<link.size();x++) { System.out.print(link.get(x)+" "); } System.out.println(); } public void myAdd(Object obj) { link.addFirst(obj); } public Object myGet() { return link.removeLast(); } public boolean isNull() { return link.isEmpty(); }}class LinkedListTest{ public static void main(String []args) { DuiLie dl = new DuiLie(); dl.myAdd("java01"); dl.myAdd("java02"); dl.myAdd("java03"); dl.myAdd("java04"); dl.bianli();//遍历 while(!dl.isNull()) { System.out.println(dl.myGet()); } }}
输出结果:
java04 java03 java02 java01 java01java02java03java04
10、集合框架(ArrayList练习)
去除ArrayList集合中的重复元素
import java.util.*;class ArrayListTest{ public static ArrayList SingleElement(ArrayList al) { //定义一个临时容器 ArrayList newAl = new ArrayList(); Iterator it = al.iterator(); while(it.hasNext()) { Object obj = it.next(); if(!newAl.contains(obj)) { newAl.add(obj); } } return newAl; } public static void main(String[]args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java01"); al.add("java02"); al.add("java04"); al.add("java06"); al.add("java01"); System.out.println("原al:"+al); System.out.println("新al:"+SingleElement(al)); }}
输出结果:
原al:[java01, java01, java02, java04, java06, java01]新al:[java01, java02, java04, java06]
11、集合框架(ArrayList练习)
将自定义对象作为元素存储到ArrayList集合中,并去除重复元素。 比如:存人对象:同姓名同年龄,视为同一个人,为重复元素。 思路: 1、对人描述 2、定义容器,将人存入。 3、取出。
代码:
import java.util.*;class Person{ private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name ; } public int getAge() { return age; } public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法 { if(!(obj instanceof Person)) { return false; } Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age; }}class ArrayListTest2{ public static ArrayList SingleElement(ArrayList al) { //定义一个容器 ArrayList newAl = new ArrayList(); Iterator it = al.iterator(); while(it.hasNext()) { Object obj = it.next(); if(!(newAl.contains(obj)))//即调用了Person类中的自定义equals函数 { newAl.add(obj); } } return newAl; } public static void main(String []args) { ArrayList al = new ArrayList(); al.add(new Person("lisi01",30)); al.add(new Person("lisi02",33)); al.add(new Person("lisi03",22)); al.add(new Person("lisi04",30)); al.add(new Person("lisi01",30)); al = SingleElement(al); Iterator it = al.iterator(); while(it.hasNext()) { Person p = (Person)it.next(); System.out.println(p.getName()+"::"+p.getAge()); } }}
输出结果:
lisi01::30lisi02::33lisi03::22lisi04::30
12、集合框架(HashSet)
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。 Set
|---HashSet:底层数据结构是哈希表
|---TreeSet
Set集合的功能和Collection是一致的。
测试代码:
import java.util.*;class HashSetDemo{ public static void main(String []args) { HashSet hs = new HashSet(); hs.add("java01"); hs.add("java02"); hs.add("java03"); hs.add("java04"); Iterator it = hs.iterator(); while(it.hasNext()) { System.out.println(it.next()); }//无序存,按哈希表顺序存。 }}
输出结果:
java04java03java02java01
13、集合框架(HashSet存储自定义对象)
往HashSet集合中存入自定义对象,姓名和年龄相同为同一个人,重复元素。
import java.util.*;class HashSetTest{ public static void main(String []args) { HashSet hs = new HashSet(); hs.add(new Person("al",11)); hs.add(new Person("a2",12)); hs.add(new Person("a3",13)); hs.add(new Person("a2",12)); Iterator it = hs.iterator(); while(it.hasNext()) { Person p = (Person)it.next(); System.out.println(p.getName()+"::"+p.getAge()); } }}class Person{ private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name ; } public int getAge() { return age; } public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法 { System.out.println("equals() run"); if(!(obj instanceof Person)) { return false; } Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age; } public int hashCode() { System.out.println("hashCode() run"); //字符串类型的变量可以调用字符串自己的哈希值函数,返回字符串自己独有的哈希值 return this.name.hashCode()+this.age*37; //为了保证哈希值唯一而在对象内容不一样的情况下不用去调用equals方法 }}
输出结果:
hashCode() runhashCode() runhashCode() runhashCode() runequals() runal::11a3::13a2::12
HashSet是如何保证元素唯一性的呢?
是通过元素(对象)的两个方法:hashCode和equals来完成,如果元素的hashCode值相同,才会判断equals是否为true,如果元素的hashCode值不同,不会调用equals。
14、集合框架(HashSet判断和删除的依据)
import java.util.*;class HashSetTest{ public static void main(String []args) { HashSet hs = new HashSet(); Person p1 = new Person("a2",12); hs.add(new Person("al",11)); hs.add(p1); hs.add(new Person("a3",13)); System.out.println("...."); //hs.add(new Person("a2",12)); System.out.println("测试判断是否包含的功能:"+hs.contains(new Person("a2",12))); hs.remove(p1); /* Iterator it = hs.iterator(); while(it.hasNext()) { Person p = (Person)it.next(); System.out.println(p.getName()+"::"+p.getAge()); } */ }}class Person{ private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name ; } public int getAge() { return age; } public boolean equals(Object obj)//List集合判断元素是否相同,依据是元素(对象)的equals方法 { System.out.println("equals() run"); if(!(obj instanceof Person)) { return false; } Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age; } public int hashCode() { System.out.println("hashCode() run"); //字符串类型的变量可以调用字符串自己的哈希值函数,返回字符串自己独有的哈希值 return this.name.hashCode()+this.age*37; //为了保证哈希值唯一而在对象内容不一样的情况下不用去调用equals方法 }}
输出结果:
hashCode() runhashCode() runhashCode() run....hashCode() runequals() run测试判断是否包含的功能:truehashCode() run
对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
- java基础问题14
- java基础--14
- Java基础14--多线程
- java基础--笔记14
- java基础14
- Java基础-14
- java基础14:多线程
- java基础(14)-- Java NIO
- java基础(14)- 线程基础
- 2011-12-14java基础
- Java基础14-集合List
- java基础第14天
- Java基础01:基础
- Java基础:基础加强
- Java基础-基础
- java基础的基础
- JAVA基础---基础常识
- Java基础:基础加强
- 域名同一文件路径,不同的域名指向不同的robots文件
- 第3周项目1-三角形类的构造函数(1、带参数的构造函数)
- Timeout expired. The timeout period elapsed prior to completion of the operation or the server...
- 【深入浅出IOS开发】IOS绘图基础
- mysql数据库千万级别数据的查询优化和分页测试
- Java基础-14
- Java web项目利用POI导出excel
- 14 css(已解决)图片垂直居中 父元素为relative且height未知(chrome)
- 面向对象中的注意点
- hdu2177取(2堆)石子游戏
- 【深入浅出IOS开发】绘制图片
- 初学者学习linux 好网站
- elasticsearch在NAS上的部署和使用
- 数据库设计误区:备用字段 / 保留字段 / 预留字段