java基础知识点整理(五)

1、什么是集合?有什么用?

数组其实就是一个集合。集合实际上就是一个容器。可以用来容纳其他类型的数据。
集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用)
List.add(100);//自动装箱Integer
注意:集合在java中本身是一个容器,一个对象。
集合中任何时候存储的是“引用”。

2、集合为什么说在开发中使用较多?

集合是一个容器,是一个载体,可以一次容纳多个对象,在实际开发中,假设连接数据库,数据库当中有10条记录,那么假设把这10条记录查询出来,在java程序中会将10数据封装成10个java对象,然后将10个java对象放到某个集合当中,将集合传到前端,然后遍历集合,将一个数据一个数据展现出来。

3、集合在java JDK中的哪一个包下?

所有的集合类和集合接口都在java.util包下。

4、在java中集合分为两大类

一类是单个方式存储元素:单个方式存储元素,这一类集合中超级父类接口:java.util.Collection;
另一类是以键值对的方式存储元素:以键值对的方式存储元素,这一类集合的超级父类接口:java.util.Map;

5、集合的继承结构图(必须背会)

集合整个体系是怎么一个结构,需要有印象!
Iterator it = “Collection对象”.iterator();
it是迭代器对象。
Collection为超级父类
Map为超级父类

6、总结集合(所有的实现类)

ArrayList:底层是数组
LinkedList:底层是双向链表
Vector:底层是数组,线程安全的,效率较低,使用较少
HashSet:底层是HashMap,放到HashSet集合中的元素等同于放到HashMap集合的key部分了。
TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到TreeMap集合的key部分了。
HashMap:底层是哈希表
Hashtable:底层也是哈希表,只不过是线程安全的,效率较低,使用较少
Properties:是线程安全的,并且key和value只能存储字符串String
TreeMap:底层是二叉树。TreeMap集合的key可以自动按照大小顺序排序。

List集合存储元素的特点:
有序可重复
有序:存进去的顺序和取出来的顺序相同,每一个元素都有下标。
可重复:存进去1,可以再存进去一个1
Set(Map)集合存储元素的特点:
无序不可重复
无序:存进去的顺序和区出口的顺序不一定相同,另外Set集合中元素没有下标。
不可重复:存进去1,不能再存进去1.
SortedSet(SortedMap)集合存储元素的特点:
首先是无序不可重复的,但是SortedSet集合中的元素是可排序的。
无序:存进去的顺序和取出来的顺序不一定相同,另外Set集合中元素没有下标。
不可重复:存进去1,不能再存进去1.
可排序:可以按照大小顺序排列。
Map集合的key就是一个Set集合。往Set集合中放数据实际上就是放到Map里的key。

7、Collection中能放什么元素?

没有使用“泛型”之前,Collection中可以存储Object所有子类型。
使用了“泛型”之后,Collection中只能存储某个具体的类型。

8、关于java.lang.Collection接口中常用的方法。

boolean add(Object e)向集合中添加元素
int size()获取集合中元素的个数
void clear()清空集合中所有元素
boolean contains(Object o)判断集合中是否包含某个元素
boolean remove(Object o)删除集合中某个元素
boolean isEmpty()判断集合是否为空(集合中是否存在元素)
Object[] toArray()调用这个方法可以把集合转换为数组(了解,使用不多)

9、关于集合的遍历/迭代

Iterator方法:
boolean hasNext()如果仍有元素可以迭代,则返回true
Object next()返回迭代的下一个元素
void remove()迭代器指向的collection中移除迭代器返回的最后一个元素(可选操作)
Iterator

//注意:以下讲解的遍历/迭代方式,是所有Collection通用的一种方式
//在Map集合中不能用,在所有的Collection以及子类中使用
Collection c = new ArrayList();
//后面的集合无所谓,主要看前面的Collection接口,怎么遍历/迭代
c.add("abc");
c.add("def");
c.add(100);
c.add(new Object());
//对集合进行遍历
//第一步:获取集合对象的迭代器对象Iterator
Iterator it = c.iterator();
//第二步:通过以上获取的迭代器对象开始迭代/遍历集合
boolean hasNext = it.hasNext;
if(hasNext){
	//存进去什么类型,取出来就是什么类型,只不过输出的时候转换成字符串
	Object obj=it.next();
	System.out.println(obj);
}

10、深入Collection集合的contains方法

boolean contains(object o);判断集合中是否包含某个元素,不包含的数返回false。
contains方法是用来判断集合中是否包含某个元素的方法,,那么它底层是怎么判断集合中是否包含某个元素的呢?
调用了equals方法进行比对的,equals方法返回true,就表示包含这个元素。

11、计算机英语:

增删改查这几个单词要知道:
增:add,save,new
删:delete,drop
改:update,set,modify
查:find,get,query,select

12、链表数据结构

单链表
链表的优点:
由于链表的元素在空间存储上内存地址不连续,所以随机增删元素的时候不会有大量元素位移,因此随机增删效率较高。
在以后的开发中,如果遇到随机增删集合中元素的业务比较多,建议使用LinkedList。
链表的缺点:
不能通过数学表达式计算被查找元素的内存地址,每一次查找都是从头开始遍历,直到找到为止。LinkedList集合检索/查找的效率较低。
ArrayList:把检索发挥到极致(末尾添加元素效率还是很高的)
LinkedList:把随机增删发挥到极致。
双向链表

13、LinkedList集合有初始化容量吗?

最初这个链表中没有任何元素。
first和last引用都是null,不管是LinkedList还是ArrayList。
以后写代码不需要关心具体是哪个集合。因为我们是面向接口编程,调用的方法都是接口的方法。

14、Vector集合

1.底层是一个数组
2.初始化容量:10
3.怎么扩容的?
扩容之后是原容量的2倍:10->20->40->80
4.ArrayList集合扩容特点:10->15->15*1.5
ArrayList扩容是原容量的1.5倍。
5.Vector中所有的方法都是线程同步的,都带有synchronized关键字,是线程安全的,效率较低,使用较少了。
6.怎么将一个线程不安全ArrayList集合转换成线程安全的呢?
使用集合工具类:java.util.Collections;
java.lang.Collection是集合接口。

//这个可能以后要用!
List myList = new ArrayList();//非线程安全的
//转换成线程安全的
Collections.synchronizedList(myList);
//myList集合就是线程安全的了
myList.add("111");
myList.add("abc");

15、泛型

1.JDK5.0之后推出的新特性:泛型
2.泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的,运行阶段泛型没用。
3.使用了泛型的好处是什么?
第一:集合中存储的元素类型统一了
第二:从集合中取出的元素类型是泛型指定的类型,不需要进行大量的“向下转型”
4.泛型的缺点:
导致集合中存储的元素缺乏多样性。
大多数业务中,集合中元素的类型还是统一的,所以这种泛型特性被大家所认可。

//使用泛型List<Animal>之后,表示集合中只允许存储Animal类型的数据
//用泛型来指定集合中存储的数据集合
List<Animal> mylist = new ArrayList<Animal>();
//准备对象
Cat c = new Cat();
Bird b = new Bird();
mylist.add(c);
mylist.add(b);
//获取迭代器
//这个表示迭代器迭代的是Animal类型
Iterator<Animal> it = mylist.iterator();
while(it.hasNext()){
	Animal a = it.next();
	//调用父类的方法不需要向下转型
	a.move();
	//但是调用子类特有的方法的话还是需要向下转型
	if(a instanceof Cat){
		Cat x = (Cat) a;
		x.catchMouse();
	}
	if(a instanceof Bird){
		Bird y = (Bird)a;
		y.fly();
	}
}

16、自动类型推断

1.JDK8之后引入的:自动类型推断(又称钻石表达式)
2.ArrayList<这里的类型自动推断>()
3.自定义泛型可以吗?可以
4.自定义泛型的时候<>尖括号中的是一个标识符,随便写。
java源代码中经常出现的是:和
E是element的单词首字母
T是type单词首字母

public class GenericTest<abc>{
	public void doSome(abc o){
		System.out.println(o);
	}
	public static void main(String[] args){
		GenericTest<String> gt = new GenericTest<>();
		gt.doSome("string");
	}
}

17、foreach

1.JDK5.0之后推出的一个新特性,叫做增强for循环 ,或者叫做foreach
2.语法:
for(元素类型 变量名:数据或者集合){}

//遍历数组(普通for循环)
for(int i=0; i<arr.length; i++){
	System.out.println(arr[i]);
}

//增强for(foreach)
//foreach有个缺点:没有下标,在需要使用下标的循环中不建议使用
for(int data:arr){
	//data代表的是数组中每个元素
	System.out.println(data);
}

18、java.util.Map接口中常用的方法

1.Map和Collection没有继承关系
2.Map集合以key和value的方式存储数据:键值对
key和value都是引用数据类型
key和value都是存储对象的内存地址
key起到主导地位,value是key的一个附属品
3.Map接口中常用的方法:
V put(K key, V value)向Map集合中添加键值对
V get(Object key)通过key获取value
void clear()清空Map集合

方法说明
boolean containsKey(Object key)判断Map中是否包含某个key
boolean containsValue(Object value)判断Map中是否包含value
boolean isEmpty()判断Map集合中元素的个数是否为零
Set keySet()获取Map集合中所有的key(所有的键是一个Set集合)
V remove(Object key)通过key删除键值对
int size()获取Map中键值对的个数
Collection values()获取Map集合中所有的value,返回一个Collection
Set<Map,Entry<K,V>> entrySet()将Map集合转换成Set集合

【注意:Map集合通过entrySet()方法转换成这个Set集合,Set集合中元素的类型是Map.Entry<K, V>】
【Map.Entry和String一样,都是一种类型的名字,只不过:Map.Entry是静态内部类,是Map中的静态内部类】

//第一种方式:Set<Map.Entry<K,V>> entrySet()
//这种方式是把Map集合直接全部转换成Set集合
//Set集合中元素的类型是Map.Entry
Set<Map.Entry<Integer,String>> set = map.entrySet();
Iterator<Map.Entry<Integer,String>> it=set.iterator();
//遍历Set集合,每一次取出一个node
while(it.hasNext()){
	Map.Entry<Integer,String> node = it.next();
	Integer key=it.getKey();
	String value = it.getValue();
	System.out,println(key +"="+value);
}

//第二种foreach方式:这种方式效率比较高,
//因为获取key和value都是直接从node对象中获取的属性值,这种方式比较适合于大数据量。
for(Map.Entry<Integer, String> node:set){
	System.out.println(node.getKey() + "=" + node.getValue();
}

19、HashMap集合

1.HashMap集合底层是哈希表/散列表的数据结构。
2.哈希表是一个怎样的数据结构呢?
哈希表是一个数组和单向链表的结合体。
数组:在查询方面效率很高,随机增删方面效率很低。
单向链表:在随机增删方面效率很高,在查询方面效率很低。
哈希表将上面两种数据结构融合起来,充分发挥它们各自的优点。
3.HashMap集合底层的源代码

public class HashMap{
	//HashMap底层实际上就是一个数组(一维数组)
	Node<K, V>[] table;
	//静态内部类
	static class Node<K, V> implements Map.Entry<K, V>{
		final int hash;//哈希值(哈希值是key的hashCode()方法的执行结果。hash值通过哈希函数/算法,可以转换存储成数组下标)
		final K key;//存储到Map集合中的那个key
		V value;//存储到Map集合中的那个value
		Node<K, V> next;//下一个节点的地址
	}
}

哈希表/散列表:一维数组,这数组中每一个元素都是一个单向链表。(数组和链表的结合体)

4.最主要掌握的是:
map.put(k, v);
v = get(k);
以上两个方法的实现原理是必须要掌握的。
HashMap

5.HashMap集合的key部分特点:无序不可重复
为什么无序?因为不一定挂到哪个单向链表上。
不可重复是怎么保证的?equals方法保证HashMap集合的key不可重复。如果key重复了,value会覆盖。

放在HashMap集合key部分的元素其实就是放到HashSet集合中了,所以HashSet集合中的元素也需要同时重写hashCode()+equals方法。

6.HashMap使用不当时无法发挥性能。
假设将所有的hashCode()方法返回固定某个值,那么会导致哈希表变成纯单向链表。这种情况我们称之为:散列分布不均匀。

假设将所有的hashCode()方法返回值都设定为不一样的值,可以吗?有什问题?
不行,因为这样的话底层哈希表就变成一维数组,就没有链表的概念了。也是散列分布不均匀 。

什么是散列分布均匀?
假设有100个元素,10个单向链表,那么每个单向链表上有10个节点,这是最好的。是散列分布均匀的。
散列分布均匀需要你重写hashCode()方法有一定的技巧。

7.重点:放在HashMap集合key部分的元素,以及放在hashSet集合中的元素,需要同时重写hashCode()和equals方法。

8.HashMap集合的默认初始化容量是16,默认加载因子是0.75
这个默认加载因子是当HashMap集合底层数组容量达到75%的时候,数组开始扩容。
重点记住:HashMap集合初始化容量必须是2的倍数,这也是官方推荐的。这是因为达到散列分布均匀,为了提高HashMap集合的存取效率,所以必须的。

20、关于HashMap

1.向Map集合中存,以及从Map集合中取,都是先调用key的hashCode()方法,然后调用equals方法。
equals方法有可能调用也有可能不调用。
拿put(k, v)举例,什么时候equals不调用?
k.hashCode()方法返回哈希值,哈希值经过哈希算法转换成数组下标。数组下标位置上如果是null,equals不会执行。
拿get(k)举例,什么时候equals不会调用
k.hashCode()方法返回哈希值,哈希值经过哈希算法转换成数组下标。数组下标位置如果是null,equals不需要执行。

2.如果一个类的equals方法重写了,那么hashCode方法必须重写,并且equals方法返回true,hashCode方法返回的值必须一样。
equals方法返回true,表示两个对象相同,在同一个单向链表上比较。那么对于同一个单向链表上的节点来说,它们的哈希值都是相同的。所以hashCode方法返回值必须相同。
3.hashCode方法和equals方法直接使用IDEA生成,但是这两个方法要同时生成。
4.终极结论:
放在HashMap集合key部分,以及放在HashSet集合中的元素,需要同时重写hashCode方法和equals方法。

   @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age;
    }

    @Override
    public int hashCode() {
        return Objects.hash(age);
    }

5.在JDK8之后,如果哈希表单向链表中元素超过8个,单向链表这种数据结构会变成红黑树数据结构,当红黑树上的节点数量小于6时,会重新把红黑树变成单向链表数据结构。这种方式也是为了提高检索效率,二叉树的检索会再次缩小扫描范围。提高效率。

6.哈希值相同的话一定是在同一个链表上。

7.对于哈希表数据来说:
如果o1和 o2的hash值相同,一定是放到同一个单向链表上。
如果o1和o2的hash值不同,但由于哈希算法执行结束之后转换的数组下标可能相同,此时会发生“哈希碰撞”
8.HashMap集合key部分允许null吗?
允许,但是要注意:HashMap集合中的key为null的值只能有一个。

21、关于Hashtable

Hashtable的key可以为null嘛?
Hashtable的key和value都是不能为null的。
HashMap集合的key和value都是可以为null。
Hashtable方法都带有synchronized:线程安全。
线程安全有其他方案,这Hashtable对线程的处理导致效率较低,使用较少了。
Hashtable和HashMap一样底层都是哈希表数据结构。
Hashtable初始化容量为11,默认加载因子为0.75.
Hashtable的扩容:原容量*2+1.

22、关于Properties

目前只需要掌握Properties属性类对象的相关方法即可。
Properties是一个Map集合,继承Hashtable,Properties被称为属性类对象。
Properties 是线程安全的。

23、关于TreeSet

1.TreeSet集合底层实际上是一个TreeMap
2.TreeMap集合底层是一个二叉树
3.TreeSet集合中的元素实际上是放到TreeMap集合的key部分。
4.TreeSet的元素:无序不可重复,但是可以按照元素的大小自动排序。称之为:可排序集合。
5.对于自定义类型来说,TreeSet可以排序吗?
如果没有指定对象之间的比较规则,是无法排序的。
6.如果程序运行的时候出现这个异常:java.lang.ClassCastException
出现这个异常的原因是:
没有实现java.laang.Comparable接口

24、自平衡二叉树

自平衡二叉树

25、Comparable和Comparator

1.Comparable是java.lang包下的,Comparator是java.util包下的。
2.Comparable对应compareTo,Comparator对应compare.
3.Comparator可以采用匿名内部类的方式实现
4.cmpareTo方法的返回值很重要:
返回0表示相同,value会覆盖
返回>0,会继续在右子树上找
返回<0,会继续在左子树上找

//放在TreeSet集合的元素需要实现java.lang.Comparable接口
//并且实现compareTo方法,equals不需要写
class Person implements Comparable<Person>{
	int age;
	public Person(int age){
		this.age=age;
	}
	public String toString(){
		return "Person[age = "+this.age + "]";
	}
	//需要在这个方法中实现比较的逻辑,或者说比较的规则,按照什么进行比较
	//拿着参数k和集合中每一个k进行比较,返回值可能是>0 <0 =0
	@Override
	public int compareTo(Person c){
		//c1.compareTo(c2)
		//this就是c1,c就是c2
		//c1和c2比较的时候,就是this和c比较
		return this.age-c.age;
	}
}
//比较器实现java.util.Comparator接口
class WuguiComparator implements Comparator<Wugui>{
	@Override
	public int compare(Wugui w1, Wugui w2){
		return w1.age-w2.age;
	}
}

//或者采用匿名内部类的方式
TreeSet<Wugui> wugui = new TreeSet<>(new Comparator<Wugui>(){
	@Override
	public int compare(Wugui o1, Wugui o2){
		return o1.age-o2.age;
	}
});

最终结论:
放到TreeSet或者TreeMap集合key部分的元素想要做到排序,包括两种方式:
第一种:放在集合中元素实现java.lang.Comparable接口
第二种:在构造TreeSet或者TreeMap集合的时候给它传一个比较器对象。
Comparable和Comparator怎么选?
当比较规则不会发生改变的时候,或者说当比较规则只有1个的时候,建议实现Comparable接口。
如果比较规则比较多,并且需要多个比较规则之间频繁切换,建议使用Comparator。
Comparator设计符合OCP原则(Open Closed Principle:开闭原则,对扩展开发,对修改关闭)

26、Collections集合工具类

java.lang.Collection集合接口
java.util.Collections集合工具类,方便集合的操作
1.ArrayList集合是线程不安全的
List list = new ArrayList<>();
变成线程安全的:
Collections.synchronizedList(list);
2.排序
Collections.sort(list);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Set:元素不可以重复,是无序。p508 Set接口中的方法和Collection一致。 |--HashSet: 内部数据结构是哈希表 ,是不同步的。 如何保证该集合的元素唯一性呢? 是通过对象的hashCode和equals方法来完成对象唯一性的。 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。 如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。 记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。 建立对象判断是否相同的依据。 import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; public class HashSetTest { public static void main(String[] args) { HashSet hs = new LinkedHashSet(); hs.add("hahah"); hs.add("hehe"); hs.add("heihei"); hs.add("xixii"); hs.add("hehe"); Iterator it = hs.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } 例子2-1: import java.util.HashSet; import java.util.Iterator; //package cn.itcast.p.bean; class Person /*extends Object*/// implements Comparable { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override//覆盖hasCode() public int hashCode() { // System.out.println(this+".......hashCode"); return name.hashCode()+age*27; // return 100; } @Override//覆盖equals方法 public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof Person)) throw new ClassCastException("类型错误"); // System.out.println(this+"....equals....."+obj); Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.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; } } //import cn.itcast.p.bean.Person; /* * 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。 */ public class HashSetTest { /** * @param args */ public static void main(String[] args) { HashSet hs = new HashSet(); /* * HashSet集合数据结构是哈希表,所以存储元素的时候, * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。 * */ hs.add(new Person("lisi4",24)); hs.add(new Person("lisi7",27)); hs.add(new Person("lisi1",21)); hs.add(new Person("lisi9",29)); hs.add(new Person("lisi7",27)); Iterator it = hs.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); //it.next()是Object对象,必须要强转,如果不强转的话,则会输出对象的哈希码 System.out.println(p); System.out.println(p.getName()+"...."+p.getAge()); } } } /* 结果如下: f:\tang>javac HashSetTest.java 注: HashSetTest.java使用了未经检查或不安全的操作。 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。 f:\tang>java HashSetTest Person@6236515 lisi9....29 Person@6236435 lisi1....21 Person@62364dd lisi7....27 Person@6236489 lisi4....24 */ 例子2-2 package test; import java.util.HashSet; import java.util.Iterator; //package cn.itcast.p.bean; class Person /*extends Object*/// implements Comparable { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override//覆盖hasCode() public int hashCode() { // System.out.println(this+".......hashCode"); return name.hashCode()+age*27; // return 100; } @Override//覆盖equals方法 public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof Person)) throw new ClassCastException("类型错误"); // System.out.println(this+"....equals....."+obj); Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.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; } @Override public String toString() { // TODO Auto-generated method stub return "姓名: "+this.name+"; 年龄"+this.age; } } //import cn.itcast.p.bean.Person; /* * 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。 */ public class HashSetDemo { public static void main(String[] args) { HashSet hs = new HashSet(); /* * HashSet集合数据结构是哈希表,所以存储元素的时候, * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。 * */ hs.add(new Person("lisi4",24)); hs.add(new Person("lisi7",27)); hs.add(new Person("lisi1",21)); hs.add(new Person("lisi9",29)); hs.add(new Person("lisi7",27)); System.out.println(hs); Iterator it = hs.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); //it.next()是Object对象,必须要强转,如果不强转的话,则会输出对象的哈希码 //System.out.println(p); //System.out.println(p.getName()+"...."+p.getAge()); } } } 输出结果如下:(和例子2有所不同,下面的结果是覆盖了父类Object的toString方法,所运行出来的结果。如果不覆盖,则输出每个对象的哈希码) [姓名: lisi9; 年龄29, 姓名: lisi1; 年龄21, 姓名: lisi7; 年龄27, 姓名: lisi4; 年龄24] 例子2-3: package test; import java.util.HashSet; import java.util.Iterator; //package cn.itcast.p.bean; class Person /*extends Object*/// implements Comparable { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override//覆盖hasCode() public int hashCode() { // System.out.println(this+".......hashCode"); return name.hashCode()+age*27; // return 100; } 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; } @Override public String toString() { // TODO Auto-generated method stub return "姓名: "+this.name+"; 年龄"+this.age; } } //import cn.itcast.p.bean.Person; /* * 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。 */ public class HashSetDemo { /** * @param args */ public static void main(String[] args) { HashSet hs = new HashSet(); /* * HashSet集合数据结构是哈希表,所以存储元素的时候, * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。 * */ //hs.add(new Demo("abc")); hs.add(new Person("lisi4",24)); hs.add(new Person("lisi7",27)); hs.add(new Person("lisi1",21)); hs.add(new Person("lisi9",29)); hs.add(new Person("lisi7",27)); //System.out.println(hs); Iterator it = hs.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); //it.next()是Object对象,必须要强转,如果不强转的话,则会输出对象的哈希码 //System.out.println(p); System.out.println(p.getName()+"...."+p.getAge()); } } } 结果如下:(由于没有覆盖equals方法的原因) lisi9....29 lisi1....21 lisi7....27 lisi7....27 lisi4....24 例子3: import java.util.HashSet; import java.util.Iterator; public class HashSetTest { public static void main(String[] args) { HashSet hs = new HashSet(); hs.add("hehe"); hs.add("heihei"); hs.add("hahah"); hs.add("xixii"); hs.add("hehe"); Iterator it = hs.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } f:\tang>javac HashSetTest.java 注: HashSetTest.java使用了未经检查或不安全的操作。 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。 f:\tang>java HashSetTest heihei hehe hahah xixii //重复的元素只会输出一次,而且无序 f:\tang> 例子4: package test; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; public class HashSetDemo { public static void main(String[] args) { HashSet hs = new HashSet(); hs.add("hahah"); hs.add("hehe"); hs.add("heihei"); hs.add("xixii"); hs.add("hehe"); hs.add(1.2);//浮点型 hs.add(1234);//整型 Iterator it = hs.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } 以上程序不会报错,运行结果如下: (是由于没有使用泛型造成的) heihei hehe 1234 hahah 1.2 xixii

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值