java--对象数组、Collection集合

对象数组、Collection集合

对象数组

  数组中不仅可以存储基本数据类型,也可以存储引用类型(也就是可以存储对象)。

代码演示

我有3个学生,请把这个3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。

学生类

public class Student {
	//定义两个私有变量,名字和年龄
    private String name;
    private int age;
    
	//通过构造函数为这两个变量赋值
    public Student(String name,int age) {
        this.name=name;
        this.age=age;
    }
    //通过getName方法返回名字
    public String getName() {
        return name;
    }
   //通过getAge方法返回年龄
    public int getAge() {
        return age;
    }
}

测试类

public class StudentText {
    public static void main(String[] args) {
    
   		 //分别创建三个Student对象
        Student stu = new Student("Sam", 50);
        Student stu1 = new Student("Jimmy", 5);
        Student stu2 = new Student("Lili", 15);
        
        //将这三个对象存储到Student类型的数组中
        Student[] s={stu,stu1,stu2};
        
        for (int i = 0; i <s.length ; i++) {
				//遍历的Student对象调用类中的方法,得到名字和年龄
                System.out.println(s[i].getName()+"  "+s[i].getAge());
        }
    }
}

结果

在这里插入代码片

集合

  为了方便对多个对象的操作,Java就提供了集合类,它只能存储引用数据类型(但这些引用类型可以是任意类型,如:Student的引用类型,Teacher的引用类型等,这些都可以一起存储在一个集合里面的),并且它的长度是可以变的。
区别
集合数组
长度区别
集合不固定数组是固定的
存储数据类型区别
只能存储引用类型数据可以存储基本数据类型数据,
也可以存储引用类型数据
内容区别
可以存储不同类型的元素里面只能存储相同类型的元素

体系图

在这里插入图片描述

Collection集合

  Collection集合它是一个接口,因此它不能实例化,但我们可以用多态的方式或直接用子类进行实例化,这样就可以调用它的方法了。
方法
boolean add(Object obj)添加一个元素
boolean addAll(Collection c)给一个集合加上另一个集合所有的元素
void clear()移除所有元素
boolean remove(Object o)移除一个元素
boolean removeAll(Collection c)除一个集合的元素(移除一个以上返回的就是true) ,删除的元素是两个集合的交集元素 如果没有交集元素 则删除失败 返回false
boolean contains(Object o)判断集合中是否包含指定的元素
boolean containsAll(Collection c)判断集合中是否包含指定的集合元素(这个集合包含另一个集合中所有的元素才算包含才返回true)
boolean isEmpty()判断集合是否为空
Iterator iterator()迭代器,用来遍历集合元素
int size()元素的个数
Object[] toArray()把集合转换为数组
boolean retainAll(Collection c)判断两个集合中是否有交集

List集合

  List集合中元素有序,并且每一个元素都存在一个索引,元素可以重复,它是Collection集合的子类,因此父类有的成员它都有,但同时它也是一个接口不能直接实例化,我们可以用多态的方式或直接用子类进行实例化,这样就可以调用它的方法了。
特有方法
get(int index)获取指定索引处的元素
set(int index,E element)更改指定索引除的值

在这里插入图片描述

List集合中的ListIterator迭代器

  ListIterator迭代器继承自父类的Iterator迭代器,因此可以使用Iterator中的方法,它也是用来遍历的。
特有功能
boolean hasPrevious()判断是否有前一个元素
E previous()返回列表中的一个元素,这个E表示任意类型
注:这两个方法可以实现数组的反向遍历,但是在进行反向遍历前,先确定指针是否在最末尾,因此通常先正向遍历,指针再能在末尾。

ArrayList类

  ArrayList集合是List集合的子类,也是它的实现类,因此用它可以调用List中的方法。

Vectror类

  Vectror类是List接口的实现类,它可以实现可增长的对象数组 , 并且它是同步的(也就是线程安全的)。
特有功能
public void addElement(E obj)在末尾添加一个任意类型数据
public E elementAt(int index)返回指索引处的一个元素,这个E表示任意类型
public Enumeration elements()返回枚举

LinkedList类

  LinkedList类是List 接口的链接列表实现类(也就是List 接口的子类),此实现不是同步的(线程不安全)。
特有功能
public void addFirst(E e)在列表开头添加一个任意类型数据
public void addLast(E e)在列表末尾添加一个任意类型数据
public E getFirst()得到列表的开头元素,E表示任意类型
public E getLast()得到列表的末尾元素,E表示任意类型
public E removeFirst()移除开头元素,E表示任意类型
public E removeLast()移除末尾元素,E表示任意类型

Set集合

  Set集合是Collection集合得到子类,因此Colletion集合的成员它都有,但同时它也是一个接口因此不能实例化,不过你可以用多态的方式实例化;它的特点是元素无序并且唯一,除了List集合的特有方法,List集合中有的方法它也有,也是一样的调用。

在这里插入图片描述

HashSet类

  HashSet类是Set接口的实现类(Set接口的子类),底层数据结构是哈希表,线程不安全,集合中的元素可以是null,它的特点是元素唯一且无序,它是通过比较两个对象hashCode() 方法是否相等和equals()方法是否相等相等,来判断这两个对象是不是同一对象,如果两个方法的结果都是相同就不存入,如果有一个不同则存,也可以说在HashSet中hashCode() 方法和equals()方法是保证元素的唯一的两个条件。
哈希表:是一个元素为链表的数组,综合了数组和链表的优点 (像新华字典一样) (JDK1.7之前)。HashSet类的元素如果遇到相同地址的元素,那么这个元素就会链接在前一个元素的开头,形成一个链表,不同地址的元素按照地址存放,就像数组一样。

LinkedHashSet类

  LinkedHashSet类是Set接口的实现类(Set接口的子类),它的底层的数据结构有链表和哈希表这两个结构,链表保证顺序,哈希表保证唯一,因此它的元素是有序且唯一的。

TreeSet类

  TreeSet是Set结构的实现类(Set接口的子类),它的底层的数据结构是二叉树,它的元素是唯一的并且它的元素是可以排序的可以,它的排序分为自然排序(必须继承Comparable接口,重写ComparaTo()方法,否则无法自然排序)和比较器排序(重写Comparator(){}中的compare()方法)。

代码演示

1、我有3个学生,请把这个3个学生的信息存储到集合中,并遍历数组,获取得到每一个学生信息。

学生类
public class Student {

    private String name;
    private int age;

    public Student(String name,int age) {
        this.name=name;
        this.age=age;
    }
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

测试类

import java.util.*;

public class Text4 {
    public static void main(String[] args) {
    
    //用多态形式定义对象,父类 Collection指向子类ArrayList,Student表示数据类型,
    //不写的话,返回的数据类型都会是Object类,你就需要强制转换类型,才能得到你所需要的Student类型
        Collection<Student> stu= new ArrayList<>();
        stu.add(new Student("Sam", 50));
        stu.add(new Student("Jimmy", 5));
        stu.add(new Student("Lili", 15));
        
	//用多态形式定义对象,父类 List指向子类ArrayList,Student表示数据类型,
    //不写的话,返回的数据类型都会是Object类,你就需要强制转换类型,才能得到你所需要的Student类型
        List<Student> stu1= new ArrayList<>();
        stu1.add(new Student("jim", 55));
        stu1.add(new Student("Jimmy", 5));
        stu1.add(new Student("linda", 35));
		
		//isEmpty()判断集合是否为空
        System.out.println("stu集合是否为空:"+stu.isEmpty());
        
        //把stu1中的元素全部加入stu中,成功放入返回true,反之则false
        boolean b = stu.addAll(stu1);
        System.out.println("是否把stu1中的元素全部加入stu中:"+b);

		//移除stu和stu1中的交集元素,如果没有交集元素,返回false,
		//有的话删除交集元素,返回true,注意这里删除的交集元素,删除的是stu中的元素,stu1的元素不变
        boolean b1 = stu.removeAll(stu1);
        System.out.println("是否删除成功:"+b1);
        
        //移除指定位置的元素remove(索引)
        Student r = stu1.remove(1);
        
        System.out.println("----------------------");
        
        //List集合中特有的遍历方法,用get得到数据,这个数据是一个对象,再用这个对象调用方法,返回年龄和名字
        for (int i = 0; i <stu1.size(); i++) {
            Student student = stu1.get(i);
            System.out.println(student.getName()+"  "+student.getAge());
        }
        
        System.out.println("----------------------");
        
        //父类Collection的迭代器,用来遍历集合,hasNext()表示还有没有下一个元素,有的话可以用next()获得
        Iterator<Student> stuiterator = stu.iterator();
        while(stuiterator.hasNext()){
            Student n1 = stuiterator.next();
            System.out.println(n1.getName()+" "+n1.getAge());
        }
        
        System.out.println("----------------------");
        
        //List中特有的迭代器ListIterator,它和Collection中的迭代器Iterator的用法相同,只不过它可以用于反向遍历
        ListIterator<Student> stuListIterator = stu1.listIterator();
        while (stuListIterator.hasNext()){
            Student n2 = stuListIterator.next();
            System.out.println(n2.getName()+" "+n2.getAge());
        }
        
        System.out.println("----------------------");
        
        //反向遍历,hasPrevious()用于判断是否有上一个元素,有的话,可以用previous()获得上一个元素
        while (stuListIterator.hasPrevious()){
            Student n2 = stuListIterator.previous();
            System.out.println(n2.getName()+" "+n2.getAge());
        }

    }
}

结果

stu集合是否为空:false
是否把stu1中的元素全部加入stu中:true
是否删除成功:true
----------------------
jim  55
linda  35
----------------------
Sam 50
Jimmy 5
Lili 15
----------------------
jim 55
linda 35
----------------------
linda 35
jim 55

  注:在用迭代器进行遍历时,是不能对集合中的元素进行增加或删除的,否则就会抛出ConcurrentModificationException(并发修改)异常,原因是我们的迭代依赖于集合,当我们往集合中添加完元素后,获取迭代器,那么迭代器已经知道了集合的元素个数,这个时候你在遍历的时候又突然想给集合里面增加或减少元素(用的是集合的add方法),那迭代器反应不过来就报错了,但如果你想要遍历时增加或减少元素也不是不可以,你只要用迭代器中的add方法就可以往里面添加元素了,你也可以使用for循环遍历,这两种方法都不会报错。
2、遍历Vector中的元素

//因为集合是位于java.util包下的,因此要导包,你可以直接导java.util.*,全部集合都在里面
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

public class VVector {
    public static void main(String[] args) {
    
    //用多态方式创建一个list对象,从父类指向子类,没有指定对象类型,好处是可以存储任意类型到集合中
        List list = new Vector();
        
    //在这里加入的100,300可不是int这个基本数据类型,而是Integer类型,它是引用类型,
    //java中会自动为int装箱为Integer,所以我们可以不用手动装箱了,addElement()方法是
    //Vector特有的,因此还要强制转换为Vector类型
        ((Vector) list).addElement(100);       
        ((Vector) list).addElement("java"); //String是引用数据类型
        ((Vector) list).addElement(300);
        
        //调用迭代器,hasNext()是迭代器中判断有没有下一个元素的方法,
        //有下一个元素的话就用next()输出这个数据
        Iterator it = list.iterator();
        while(it.hasNext()){
      //Object n = it.next();其实 it.next()返回的是Object类型,因为创建对象时前面没有规定类型
            System.out.println(it.next());//就算这里不写toString()方法,也会默认调用,因此输出的不是Object类型
        }
    }
}

结果

100
java
300

3、TreeSet存储Integer类型的元素并遍历,存储下列元素: 20 , 18 , 23 , 22 , 17 , 24, 19 , 18 , 24,并按从小到大顺序输出。

public class Tree {
    public static void main(String[] args) {
    
  		  //创建一个TreeSet对象
        TreeSet<Integer> treeSet = new TreeSet<>();
        
        //在集合中存入Integer类型数据
        treeSet.add(20);
        treeSet.add(18);
        treeSet.add(23);
        treeSet.add(22);
        treeSet.add(17);
        treeSet.add(24);
        treeSet.add(19);
        treeSet.add(18);
        treeSet.add(24);
        
        //遍历集合中的元素
        for (Integer integer : treeSet) {
            System.out.println(integer);
        }
    }
}

结果

17
18
19
20
22
23
24

你可能会疑惑,自然排序不是需要继承Comparable接口,重写ComparaTo()方法?确实是这样的,但这是在自定义的类中,你才需要这么做;而基本数据类型的包装类中,可以不必这么做,它会自动排序好(从小到大排序),不过你需要从大到小排序,就需要那么做。

在这里插入图片描述
4、键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。

学生类

public class Student1 {
    private String name;
    private int chinese;
    private int math;
    private int english;
    private int totalScore;

    public void setName(String name) {
        this.name = name;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public void setEnglish(int english) {
        this.english = english;
    }



    public String getName() {
        return name;
    }

    public int getChinese() {
        return chinese;
    }

    public int getMath() {
        return math;
    }

    public int getEnglish() {
        return english;
    }

    public int sum(){
        totalScore=chinese+math+english;
        return totalScore;
    }

}

测试类

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Text2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //创建一个 泛型为Student1的TreeSet对象,因为要存储的是Student1对象
        //并且从写比较器中的compare()方法
        TreeSet<Student1> stu = new TreeSet<>(new Comparator<Student1>() {
            @Override
            public int compare(Student1 t1, Student1 t2) {
            //如果两个对象的总分一样,那么返回t1.getName().compareTo(t2.getName()),
            //否则返回t1.sum()-t2.sum(),然后其它机制收到了这个 compare()方法的返回值
            //然后对总分进行排序(从小到大排),如果想从大到小排,就在num前加个负号
                int num=(t1.sum()-t2.sum()==0)?(t1.getName().compareTo(t2.getName())):(t1.sum()-t2.sum());
                return num;
            }
        });
        for (int i = 1; i <= 5; i++) {
            Student1 stu1 = new Student1();
            System.out.println("请输入第"+i+"个学生姓名");
            stu1.setName(sc.next());
            System.out.println("请输入第"+i+"个学生语文成绩");
            stu1.setChinese(sc.nextInt());
            System.out.println("请输入第"+i+"个学生数学成绩");
            stu1.setMath(sc.nextInt());
            System.out.println("请输入第"+i+"个学生英语成绩");
            stu1.setEnglish(sc.nextInt());
            stu.add(stu1);
        }
        System.out.println("姓名  语文成绩    数学成绩    英语成绩    总成绩");
        //遍历 TreeSet对象stu中的Student1 对象
        for (Student1 student : stu) {
            //因为遍历的是对象,因此可以通过对象名调用方法,获取需要输出的数据
            System.out.println(student.getName()+"\t\t"+student.getChinese()+"\t\t"+student.getMath()+"\t\t"+student.getEnglish()+"\t\t"+student.sum());
        }
    }
}

结果

请输入第1个学生姓名
jack
请输入第1个学生语文成绩
23
请输入第1个学生数学成绩
34
请输入第1个学生英语成绩
45
请输入第2个学生姓名
jim
请输入第2个学生语文成绩
45
请输入第2个学生数学成绩
67
请输入第2个学生英语成绩
89
请输入第3个学生姓名
sam
请输入第3个学生语文成绩
67
请输入第3个学生数学成绩
89
请输入第3个学生英语成绩
45
请输入第4个学生姓名
lucy
请输入第4个学生语文成绩
56
请输入第4个学生数学成绩
78
请输入第4个学生英语成绩
55
请输入第5个学生姓名
rose
请输入第5个学生语文成绩
77
请输入第5个学生数学成绩
45
请输入第5个学生英语成绩
67
姓名  语文成绩    数学成绩    英语成绩    总成绩
jack		23		34		45		102
lucy		56		78		55		189
rose		77		45		67		189
jim		45		67		89		201
sam		67		89		45		201
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值