Java学习lesson 15

*Set集合

一个包含重复的元素collection,并且最多包含一个null元素,此类实现Set接口,有哈希表支持,Java中的预定义类型如String、Integer都可以在集合内使用;但对于自己创建的类型是,要注意到Set

需要一种方式来维护存储顺序,而存储顺序如何维护,则是在Set的不同实现间会有所变化。因此,不同的Set实现不仅具有不同的行为,而且他们对于可以在特定是我Set抓狂那个放置的元素类型也有不同要求

继承自Collection集合,哈希表通过它的自实现类HashSet集合实例化,HashSet集合底层是HashMap的实现

*List集合与Set集合的区别

List集合:元素是不唯一的,有序性(存储和取出是不一致的)

Set集合:元素是唯一的,存储和取出是不一致的

自定义存储对象没有重写 hashCode与equals方法,将无法保证元素的唯一性

package set;

import java.util.HashSet;
import java.util.Set;

public class SetDemo {

	public static void main(String[] args) {
	//创建Set集合对象,Set集合是通过HashSet实现的
         Set<String> set=new HashSet<String>();
         //向集合中添加元素
         set.add("hello");
         set.add("hello");
         set.add("JavaSE");
         set.add("world");
         set.add("world");
         set.add("Java");
         
         //增强for循环,遍历元素
         for(String str : set){
        	 System.out.println(str);
         }
	}

}

*HashSet集合的add()方法,底层依赖于双列集合HashMap<K,V>的put(K key,V value)来实现的

put(K key,V value)底层是依赖于HashCod()和equals()

传递元素的时候,首先判断的是每一个元素对应的HashCode值是否一样,如果HashCode值一样,还要比较他们的equals()方法。由于现在集合存储的是String类型,String类型本身重写了equals()方法,所以默认比较的是内容是否相同,这里最终返回的就是第一次存储的那个元素,由此保证集合内元素的唯一性

(为快速查找而设计的Set,存入HashSet的元素必须定义hashCode())

package set;

import java.io.Serializable;
import java.util.HashSet;

public class HashSetDemo1 implements Serializable{
	private static final long serialVersionUID = 1L;
	transient int num ;
	public static void main(String[] args) {
		//创建集合对象 
		HashSet<String> hs=new HashSet<String>();
		//向集合中添加元素
		hs.add("hello");
		hs.add("world");
		hs.add("hello");
		hs.add("JavaSe");
		hs.add("Java");
		hs.add("word");
		hs.add("JavaWab");
		//加强for循环,遍历集合
		for(String str :hs){
			System.out.println(str);
		}
	}

}

//需求:存储自定义对象并遍历(使用HashSet集合)

HashSet<Student>()

package set;
//自定义类
public class Student {
	private String name;
	private int age;
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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;
	}

}

//测试类

package set;

import java.util.HashSet;

public class HashSetDemo {
	public static void main(String[] args){
		//创建HashSet集合对象
		HashSet<Student> hs=new HashSet<Student>();
		//创建学生对象
		Student st1=new Student("苹果",3);
		Student st2=new Student("梨",24);
		Student st3=new Student("桔子",15);
		Student st4=new Student("桔子",15);
		Student st5=new Student("桔子",17);
		Student st6=new Student("核桃",21);
		//向集合中添加元素
		hs.add(st1);
		hs.add(st2);
		hs.add(st3);
		hs.add(st4);
		hs.add(st5);
		hs.add(st6);
		//增强for循环,遍历集合
		for(Student st :hs){
			System.out.println(st.getName()+"-----"+st.getAge());
		}

	}

}

*TreeSet(Set集合的重点)

(保持次序的Set,底层依赖于TreeMap实例,底层为红黑树结构,可以从Set中提取有序的序列)

*有两个构造方法(取决于开发者使用的是什么养的构造方法)

*public TreeSet():无参构造:根据其元素的自然顺序进行排序

package treeset;

import java.util.TreeSet;

public class TreeSetDemo {

	public static void main(String[] args) {

		//调用无参构造;元素将以自然排序进行排序
		TreeSet<Integer> ts=new TreeSet<Integer>();
		//向集合中添加元素
		ts.add(67);
		ts.add(45);
		ts.add(64);
		ts.add(98);
		ts.add(23);
		//遍历元素
		for(Integer in : ts){
			System.out.print(in+" ");
		}
	}

}

*publict TreeSet(Comparaptr<E> com)

*对于TreeSet集合要实现自然排序,那么该集合中存储的自定义类型必须实现Comparable接口,      并且必须重写该接口中的CompareTo()方法

*重写了Comparable接口中的CompareTo方法中代码需要自己给出(排序模式)

package treeset;
//对于TreeSet集合存储自定义对象必须实现一个接口:compareable接口
public class Student implements Comparable<Student> {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		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;
	}

	public int compareTo(Student st) {
		//排序的代码了,需要定义排序的条件
		//主要条件:按照学生的年龄从小到大进行排序
		int num =st.age - this.age ;//年龄从大到小 
               //比较完主要条件,还要还要比较次要条件:姓名内容也需要相同
		int num2 = num==0 ? this.name.compareTo(st.name): num ;
		return num2 ;
	}
}  
package treeset;

import java.util.TreeSet;

public class TreeSetDemo1 {
	public static void main(String[] args){
		//创建对象
		TreeSet<Student> ts=new TreeSet<Student>();
		//创建Student对象
		Student st1=new Student("山鬼谣",24);
		Student st2=new Student("山鬼谣",25);
		Student st3=new Student("弋痕夕",24);
		Student st4=new Student("山鬼谣",24);
		Student st5=new Student("千钧",15);
		Student st6=new Student("千钧",17);
		Student st7=new Student("辰月",16);
		//向集合中添加元素
		ts.add(st1);
		ts.add(st2);
		ts.add(st3);
		ts.add(st4);
		ts.add(st5);
		ts.add(st6);
		ts.add(st7);
		//遍历元素,按年龄降序排列
		for(Student st : ts){
			System.out.println(st.getName()+"----"+st.getAge());
		}
	}
}

//键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

package treeset;

public class Student1 {
	private String name;
	private int chineseScore;
	private int englishScore;
	private int mathScore;
	public Student1() {
		super();
	}
	public Student1(String name, int chineseScore, int englishScore,
			int mathScore) {
		super();
		this.name = name;
		this.chineseScore = chineseScore;
		this.englishScore = englishScore;
		this.mathScore = mathScore;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getChineseScore() {
		return chineseScore;
	}
	public void setChineseScore(int chineseScore) {
		this.chineseScore = chineseScore;
	}
	public int getEnglishScore() {
		return englishScore;
	}
	public void setEnglishScore(int englishScore) {
		this.englishScore = englishScore;
	}
	public int getMathScore() {
		return mathScore;
	}
	public void setMathScore(int mathScore) {
		this.mathScore = mathScore;
	}

	public int getSum(){
		return this.chineseScore+this.englishScore+this.mathScore;
	}
}

package treeset;

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

public class TreeSetDemo2 {

	public static void main(String[] args) {
		// 创建TreeSet集合对象,使用有参构造
		// 比较器排序匿名内部类的方式
		TreeSet<Student1> ts = new TreeSet<Student1>(new Comparator<Student1>() {
			public int compare(Student1 st1, Student1 st2) {
		// 主要条件:总分从高到到第进行排序
				int num = st2.getSum() - st1.getSum();

				// 总分相同,不一定语文成绩相同,比较语文成绩
				int num2 = num == 0 ? st1.getChineseScore() - st2.getChineseScore() : num;

				// 总分相同,语文成绩相同,比较数学成绩
				int num3 = num2 == 0 ? st1.getEnglishScore() - st2.getEnglishScore() : num2;

				// 总分相同,语文成绩相同,数学相同,比较英语
				int num4 = num3 == 0 ? st1.getMathScore() - st2.getMathScore() : num3;

				// 总分以及各科成绩都相同,不一定是同一个人,姓名内容是否相同
				int num5 = num4 == 0 ? st1.getName().compareTo(st2.getName()): num4;
				return num5;
				}
				});

				System.out.println("录入学生信息开始:");
				// 键盘录入5个学生的信息,姓名,语文成绩,数学成绩,英语成绩
				for (int i=1;i<=5;i++) {
					// 创建键盘录入对象
					// 为了方便录入数据,数据类型都使用String类型接收
					Scanner sc = new Scanner(System.in);
					System.out.println("请输入第"+i+"个学生的姓名:");
					String name = sc.nextLine();
					System.out.println("请输入第" +i+ "个学生的语文成绩:");
					String chineseStr = sc.nextLine();
					System.out.println("请输入第" +i+ "个学生的英语成绩:");
					String mathStr = sc.nextLine();
					System.out.println("请输入第" +i+ "个学生的数学成绩:");
					String englishStr = sc.nextLine();

					// 创建一个学生对象,把这些信息封装到学生对象中
					Student1 st = new Student1();
					st.setName(name);
					st.setChineseScore(Integer.parseInt(chineseStr));
					st.setEnglishScore(Integer.parseInt(mathStr));
					st.setMathScore(Integer.parseInt(englishStr));

					// 将学生对象添加到集合中
					ts.add(st);
				}

				System.out.println("学生信息录入结束:");
				System.out.println("学生信息总分从高到底排列如下:");
				//\t是制表符
				System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");

				// 增强for遍历集合
				for (Student1 std : ts) {
					System.out.println(std.getName() + "\t" + std.getChineseScore() + "\t"
							+ std.getEnglishScore() + "\t" + std.getMathScore());
				}
	}

}

*对自定义对象什么情况下保证元素是唯一的

成员变量相同,认为是同一个元素

主要条件给定,需要分析次要条件

*使用比较器排序,使用匿名内部类

使用有参构造创建TreeSet集合对象

*LinkedHashSet<E>

具有可预知顺序的Set接口的哈希表链表实现

*由哈希保证元素的唯一性,有链接列表保证元素的有序性

package linkedhashset;

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {
	public static void main(String[] args) {
		//创建LinkedHashSet集合对象
		LinkedHashSet<String> link = new LinkedHashSet<String>();

		//给集合中添加元素
		link.add("hello") ;
		link.add("hello") ;
		link.add("world") ;
		link.add("Java") ;
		link.add("JavaSE") ;
		link.add("world") ;

		//增强 for循环,遍历集合
		for(String s: link){
					System.out.println(s);
				}
	}

}

时间: 2024-08-06 15:03:24

Java学习lesson 15的相关文章

Java学习lesson 02

常量 什么是常量 * 在程序执行的过程中其值不可以发生改变  Java中常量的分类 * 字面值常量 * 字符串常量                          * 整数常量                     * 小数常量                     * 字符常量                     * 布尔常量                     * 空常量            null(数组部分讲解) * 自定义常量 eclipse实现 class Demo1

Java学习lesson 12

*数组的高级排序 *冒泡排序 两个两个比较,大的往后 *选择排序 从0索引开始,用它对应的元素一次和后面遏制进行比小的往前放,第一次比较完毕,最小值出现在了最小索引处, *1)用0索引对应的元素依次和后面的索引对应的元素进行比较 比length.arr-1次 *二分查找;二分搜索法 *前提条件:数组必须是有序的(一个排好序的数组) *思想:猜想中间的索引,这要可以将数组减半 *步骤: 1)定义最小索引,最大索引 2)计算中间索引 3)拿中间索引的元素和要查找的索引进行比较 相等:直接返回中间索引

我的java学习笔记(15)关于接口

1.接口技术主要用来描述具有什么功能,而并不给出每个功能的具体实现. 2.一个类可以实现一个或多个接口,并在需要接口的地方,随时使用实现了相应接口的对象. 3.在java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类的需求要遵从接口描述的统一格式进行定义. 4.接口中的所有方法自动的属于public. 5.接口决不能含有实例域,也不能在接口中实现方法. 6.提供实例域和方法实现的任务应该由实现接口的那个类来完成. 7.可以将接口看成是没有实例域的抽象类.但是这两个概念还是有区别的.

java学习lesson 01

Java语言平台:    * JSE      开发普通桌面和商务应用程序,该技术体系是其他两者的基础, * JME      开发电子消费产品和嵌入式设备    * JEE     开发企业环境下的应用程序. Java语言特点    * 面向对象:            * 开源:    * 跨平台:Java的跨平台并不是真正的的跨平台,而是java本身采用的是半解释.半编译的方             法,并定义了Java虚拟机(JVM)的概念.Java源代码先经过Java编译器(javac

Java学习lesson 11

String类中的其他功能: 替换功能: * public String replace(char oldChar,char newChar):将字符串中某一个字符用新的字符替换 * public String replace(String oldStr,String newStr):将字符串中某一个子字符串用新 的字符                                     串去替代 * public String trim():去除字符串两端空格: * public int

Java学习lesson 10

API(应用程序编程接口) *  public final Class getClass();//返回Object的运行类(java的反射机制学) *  Class类中有一个类 *public String getName();//以String类型返回它所表示的实体(获取当前正在运行的类         的全路径) *  Integer类中有一个方法 public  static String toHexString(int i);//将一个int类型的数据转换成一个人十六进制的    字符串

Java学习心得15

学习情况:一般. 心得:无. 感受:无. 问题:因为一些个人习惯,打算针对身份证编程题做些改动.身份证的主要操作是查找,年龄和出生地这两种查找,其次是字典序输出全部数据.但是,我对数据内容不是很接收,一个是出生地,另一个是年龄.出生地,全国那么多地名,只写几个做实验,我不是很接受.年龄方面都是20几岁的.我打算改成宫崎骏动画角色查询,每个角色包含:所属动漫,上映时间,其它译名(或者英文名).与原来的程序相比,查询方式也有所改变,分成角色.动漫.年代三种查找方式,角色是精确到个的,动漫会把数据里面

Java学习笔记15

Object类是所有类.数组.枚举类的父类,是类层次结构的根类.每个类都使用Object作为超类.所有对象(包括 数组)都实现这个类的方法. Object类实现了以下方法: 我们来看看源码中toString()方法是如何定义的: public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } 通过以下程序可以看出toString()方法返回的是这个类的全称

java学习第15天(补充可变参数)

如果我们在写方法的时候,参数个数不明确,就应该定义可变参数. 格式: 修饰符 返回值类型 方法名(数据类型... 变量) {} 注意: A:该变量其实是一个数组名 B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后 举例: public static int sum(int... a) { int s=0; for(int x:a){ s+=x; } return a; } 此时如果我们在主函数中调用sum函数,都是正确的. sum(20) sum(20,30) sum(20,20,