集合概念:
对象封装数据,对象多了也需要存储,集合用于存储对象。集合又称为类集或容器。
集合与数组之间的区别:
数组的长度一旦定义,就是固定不变的,而集合的长度是可变的;
数组可以用来存储基本数据类型,也可以存储引用数据类型,而集合只能存储引用数据类型;
数组储存数据必须为同一数据类型,而集合可以存储不同的数据类型。
Collection接口
**Collection概念:**Collection位于集合类的顶层,Collection接口定义如下,
public interface Collection extends Iterable
Collection:
|——List:集合中允许存放重复的元素,有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。
|——Set:Set是一个不包含重复元素的Collection。Set允许包含null元素,但是至于需同一个Set集合只允许一个null元素,无序(存入和取出顺序有可能不一致)
Collection中常用的方法:
package CollectionDemo;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String args[]){
ArrayList al = new ArrayList();
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java4");
al.add("java5");
sop(al.contains("java1")); //如果此 collection 包含指定的元素,则返回 true。
sop(al.isEmpty()); //如果此 collection 不包含元素,则返回 true。
sop(al.size()); //返回此 collection 中的元素数。
//sop("al:"+al); //原al中存在的元素
//al.remove(0); //从此 collection 中移除指定位置的单个实例,如果存在的话(可选操作)。
//al.remove("java2"); //从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
//sop("al:"+al); //remove后al中在的元素
Iterator i = al.iterator(); //返回在此 collection 的元素上进行迭代的迭代器。
while(i.hasNext()){ //遍历al中的元素
sop(i.next());
}
al.clear(); //移除此 collection 中的所有元素(可选操作)。
sop(al);
}
public static void sop(Object obj){ //定义了一个可以打印任何类型的函数
System.out.println(obj);
}
}
Iterator接口:
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口。也就说,只要通过该接口就可以取出Collection集合中的元素,至于每一个具体的容器依据自己的数据结构,如何实现的具体取出细节,这个不用关心,这样就降低了取出元素和具体集合的耦合性。
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("abc0");
coll.add("abc1");
coll.add("abc2");
//--------------方式1----------------------
Iterator it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//---------------方式2用此种----------------------
for(Iterator it = coll.iterator();it.hasNext(); ){
System.out.println(it.next());
}
}
List接口:
List概念:List接口是一个有序集合,其元素以线性方式存储,集合中允许存放重复的元素。
List
|--ArrayList:ArrayList代替了Vector,具有查询速度非常快的特点,线程不同步,底层的数据结构是数组。
|--LinkedList:LinkedList具有增删速度非常快的特点,线程不同步,底层的数据结构是链表。
|--Vector:Vector无论查询速度还是增删速度都很慢,所以被取代,线程是同步的,底层的数据结构是数组。
List中常用的方法:
package ListDemo;
import java.util.ArrayList;
public class ListDemo {
public static void main(String[] args) {
ArrayList al1 = new ArrayList();
al1.add("java1");
al1.add("java2");
al1.add("java3");
al1.add("java4");
al1.add("java5");
ArrayList al2 = new ArrayList();
al2.add("java1");
al2.add("java2");
al2.add("java3");
al2.add("java4");
//al2.add("java5");
sop(al1.equals(al2)); //比较指定的对象与列表是否相等。
sop(al1.containsAll(al2)); //如果列表包含指定 collection 的所有元素,则返回 true。
sop(al1.get(1)); //返回列表中指定位置的元素。
sop(al1.indexOf("java6")); //返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
sop(al1.set(0, "java22")); //用指定元素替换列表中指定位置的元素(返回值为被取代的元素)。
sop(al1.subList(2, 4)); //返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
}
public static void sop(Object obj){
System.out.println(obj);
}
}
LinkedList的几个功能
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addFirst("a");
list.addFirst("b");
list.addFirst("c");
list.addFirst("d"); //在第一个位置添加
//list.addLast("e"); //在末尾追加
System.out.println(list);
Object obj1 = list.getFirst(); //获取集合中的第一个元素
System.out.println(obj1);
Object obj2 = list.getLast(); //获取集合中的最后一个元素
System.out.println(obj2);
System.out.println(list);
Object obj3 = list.removeFirst(); //删除集合中的第一个元素
System.out.println(obj3);
Object obj4 = list.removeLast(); //删除集合中的最后一个元素
System.out.println(obj4);
System.out.println(list);
}
Vector中的几个功能
public static void main(String[] args) {
Vector v = new Vector(); //创建集合对象,List的子类
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d");
//Vector迭代
Enumeration en = v.elements(); //获取枚举
while(en.hasMoreElements()) { //判断集合中是否有元素
System.out.println(en.nextElement());//获取集合中的元素
}
}
}
Set接口:
**Set概念:**Set是一个不包含重复元素的Collection,Set允许包含null值,但是只允许同一个Set集合中只包含一个null元素,也就是说Set集合不能包含重复的元素。
Set
|——HashSet:HashSet集合线程是不同步的,无序,高效,底层的数据结构是哈希表。HashSet集合保证元素唯一性:通过元素的hashCode方法,和equals方法完成的。当元素的hashCode值相同时,才继续判断元素的equals是否为true。 如果为true,那么视为相同元素,不存。如果为false,那么存储。 如果hashCode值不同,那么不判断equals,从而提高对象比较的速度。
|——LinkedHashSet:有序,hashset的子类。
|——TreeSet:对Set集合中的元素的进行指定顺序的排序,线程是不同步的,底层的的数据结构是二叉树。
HashSet去重复:
import java.util.*;
/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
*/
class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
// hs.add(new Person("a2",12));
// hs.add(new Person("a4",14));
//sop("a1:"+hs.contains(new Person("a2",12)));
// hs.remove(new Person("a4",13));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public int hashCode()
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
TreeSet
用于对Set集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。
如果元素不具备比较性,在运行时会发生ClassCastException异常。
所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。
依据compareTo方法的返回值,确定元素在TreeSet数据结构中的位置。
TreeSet方法保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果return 0,视为两个对象重复,不存。
注意:在进行比较时,如果判断元素不唯一,比如,同姓名,同年龄,才视为同一个人。
在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。
TreeSet集合排序有两种方式,Comparable和Comparator区别:
1:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。
2:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
第二种方式较为灵活。
TreeSet去重复:
import java.util.*;
/*
TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。也种方式也成为元素的自然顺序,或者叫做默认顺序。
TreeSet排序的第二种方式:当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主。
定义一个类,实现Comparator接口,覆盖compare方法。
*/
class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
//return 0;
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
//System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
/**/
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
//ts.add(new Student("lisi007",20));
//ts.add(new Student("lisi01",40));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num==0)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
/*
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
}
return num;
}
}
增强for循环
package cn.itcast.vector;
import java.util.ArrayList;
import cn.itcast.been.Student;
public class DemoFor {
public static void main(String[] args) {
//demo1();
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("李四",23));
list.add(new Student("李桶",26));
list.add(new Student("李盆",25));
list.add(new Student("李完",28));
for (Student s : list) {//增强for循环
System.out.println(s.getName()+" ,"+ s.getAge());
}
}
private static void demo1() {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for (String s: list) {//元素数据类型 变量名: 集合或数组
System.out.println(s);
}
}
}
静态导入
package cn.itcast.list;
import static java.util.Arrays.sort;//静态导入
import static java.util.Arrays.toString;
public class Demo08_StaticImport {
/*
静态导入:其实导入的是静态的方法,只要是静态的方法都可以用静态导入
*/
public static void main(String[] args) {
int[] arr = {55,44,33,22,11};
sort(arr); //排序。静态导入后这里就不用写成Arrays.sort(arr);
//System.out.println(toString(arr)); //数组转换成字符串并打印,和其他toString方法冲突
}
}
可变参数
public class DemoKeBian {
public static void main(String[] args) {
int[] arr = {22,33,44};
//print(arr);//将数组的地址值传给print方法
}
/*public static void print(int[] arr){//将数组参数传给方法
for (int i : arr) {//遍历数组
System.out.println(i);
}
}*///这两种参数能起到一样的效果但是可变参数功能强大可以接受地址传入也可接受值传入,其实就是可以变化的数组
// print{22,33,33,44};
// print();都可传入可变参数接受范围是0到无穷大
public static void print (int x,int ...arr){//将可变参数传给方法
for (int i : arr) {//遍历数组
System.out.println(i);
}
}
print(22,33,33,44);//给上下两个方法传值进行比较
public static void print (int ...arr,int x){//上面不报错运行正常,
//这里报错是因为intx接不到数据都被可变参数吃掉
for (int i : arr) {
System.out.println(i);
}
}
}