在存储的时候通常考虑的对象是数组
或者集合
,但在java中数组存在一些弊端,一旦创建,其长度不可变,在数组中真实存储的对象个数是个未知数.
一 : Collection接口
其子接口有List
与 Set
.
List
接口其主要面向存储有序的,可以重复的元素
List
接口的主要实现类是 ArrayList
与linkedList
ArrayList是List
接口的主要实现类,LinkedList
面向比较频繁的操作如删除操作,因为其实现方式主要是链表.
Set
接口主要面向的是存储无序的,不可重复的元素
Set
接口的主要实现类为HashSet,LinkedHashSet,TreeSet,Hashtable(子类 : Properties)
Collection接口提供一些通用的方法,下面一一介绍一下
-
Size();
返回集合中元素的个数
Collection coll = new ArrayList();
System.out.println(coll.size());
-
add(Oject obj);
向集合中添加元素
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
coll.add(new Date());
coll.add("BB");
System.out.println(coll);
打印结果
[123, AA, Tue Jul 17 16:59:47 CST 2018, BB]
-
addAll
向集合中添加另一个集合
Collection coll = new ArrayList();
coll.add("AA");
Collection coll1 = Arrays.asList(1,2,3);
coll.addAll(coll1);
-
isEmpty()
判断集合是否为空
Collection coll = new ArrayList();
System.out.println(coll.isEmpty());
-
clear() 清空集合元素
Collection coll = new ArrayList();
coll.add("AA");
coll.clear();
-
contains(Object obj)
判断集合是否包含指定的obj元素,如果包含返回true,否则返回false.
如果存入集合中的元素是自定义类的对象,自定义类要重写equals()
方法,添加进List集合的元素(或者对象)所在类一定要重写equals()
方法
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
boolean b1 = coll.contains(123);
判断是否包含自定义对象
Person p = new Person();
boolean b2 = coll.contains(p);
自定义类Person类
要重写 equals()
方法
class Person{
//属性部分
private String name;
private int age;
public Person() {
super();
}
//构造方法
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//set/get方法
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;
}
//重写toString
@Override
public String toString() {
return "person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
-
containsAll(coll)
判断是否包含所有元素
Collection coll1 = new ArrayList();
coll1.add(123);
coll1.add("AA");
boolean b3 = coll.containsAll(coll1);
-
retainAll(coll)
求当前集合与参数集合的共有元素,返回给当前集合
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
Collection coll1 = new ArrayList();
coll1.add(234);
coll1.add("AA");
coll.retainAll(coll1);
System.out.println(coll);
-
remove(Object obj)
删除集合中obj元素,若删除成功返回True,否则返回false
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
boolean b = coll.remove("123");
System.out.println(b);
-
removeAll(Collection coll)
从当前集合中删除包含coll中元素
coll.removeAll(coll1);
System.out.println(coll);
-
equals(Object obj)
判断集合中的所有元素是否完全相同
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
Collection coll1 = new ArrayList();
coll1.add(234);
coll1.add("AA");
System.out.println(coll1.equals(coll2));
-
hashCode();
返回集合哈希值
Collection coll1 = new ArrayList();
coll1.add(234);
System.out.println(coll1.hashCode());
-
toArray()
将集合转化成数组
Collection coll = new ArrayList();
coll.add(123);//123 自动转换成包装类
coll.add("AA");
Object[] obj = coll.toArray();
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
-
iterator()
返回一个Iterator接口实现类的对象.实现集合的遍历
Iterator iterator = coll.iterator();
System.out.println(iterator.next());
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
list接口
ArrayList
list的主要实现类
-
在指定的索引位置index添加元素
List list = new ArrayList();
list.add(123);
list.add(456);
//在指定的索引位置index添加元素
list.add(0,55);
-
获取指定索引的元素
List list = new ArrayList();
list.add(123);
list.add(456);
Object obj = list.get(1);
-
删除指定索引位置的元素
List list = new ArrayList();
list.add(123);
list.add(456);
list.remove(0);
-
设置指定索引位置的元素
List list = new ArrayList();
list.add(123);
list.add(456);
list.set(0, 111);
-
返回obj在集合中首次出现的位置 没有的话返回-1
List list = new ArrayList();
list.add(123);
list.add(456);
list.indexOf(123);
-
返回obj在集合中最后一次出现的位置 没有的话返回-1
List list = new ArrayList();
list.add(123);
list.add(456);
list.lastIndexOf(456);
-
返回从fromIndex 到toIndex结束的一个子list
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(new String("aa"));
list.add(new String("bb"));
list.subList(0, 3);//不含末尾,包含头 左闭右开
LinkedList
主要使用链表实现,适用于频繁的操作,其操作放与ArrayList
相同
LinkedList list = new LinkedList();
list.add(123);
list.add(456);
list.add("雪芙");
list.add("百百");
list.set(1, 111);
list.remove(0);
list.get(0);
/增强for循环/
for(Object o:list) {
System.out.println(o);
}
set接口
Set
接口,存储无序的,不可重复的元素,Set中常用的方法都是Collection下定义的.
Set
存储的元素是无序的,不可重复的!
1.无序性,无序性!= 随机性 ,真正的无序性指的的是元素在底层存储的位置是无序的
2.不可重复性,当向Set
中添加进相同的元素的时候,后面的这个不能添加进去.
3.要求添加进Set的元素所在的类,一定要重写equals()
和 hasCode()
方法,进而保证Set中元素的不可重复性!
Set
中的元素的存储方式
: 使用了哈希算法,当向Set中添加对象时,首先调用此对象所在类的hashCode()
方法,计算此对象的哈希值,此哈希值决定了此对象在Set中的存储位置,若此位置之前没有对象存储,则这个对象直接存到此位置.若此位置已经有对象存储,再通过equals()
比较这两个对象是否相同,如果相同,后一个对象就不能再添加进来
要求:hashCode()
方法要与equals
方法一致
子接口
- HashSet(主要实现类)
- LinkedHashSet
- TreeSet
-
HashSet
public void testHashSet() {
Set set = new HashSet();
set.add(123);
set.add(456);
set.add("xf");
set.add("xf");
set.add(null);
Personzz p1 = new Personzz("雪芙", 23);
Personzz p2 = new Personzz("雨辰", 22);
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
set.add(p1);
set.add(p2);
System.out.println(set.size());
System.out.println(set);
}
class Personzz {
String name;
Integer age;
public Personzz(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {// return age.hashcode()+name.hashcode(); 没有自带的健壮性好
final int prime = 31;// 质数
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Personzz other = (Personzz) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
打印结果
1232761
1236019
6
[null, com.TianTianBaby.java.Personzz@12dc33, 456, 123, com.TianTianBaby.java.Personzz@12cf79, xf]
-
LinkedHashSet
使用链表维护了一个添加进集合的顺序,导致我们遍历LinkedHashSet
集合元素时,是按照添加进去的顺序遍历的.
LinkedHashSet
插入性能略低于HashSet
因为链表要先破坏之前的连接,但在迭代访问Set里的全部元素时有很好的性能.
public void tesLinkedHashSet() {
Set set = new LinkedHashSet();
set.add(123);
set.add(456);
set.add("xf");
set.add("xf");
set.add(null);
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
打印结果
123
456
xf
null
-
TreeSet
①.向TreeSet
中添加的元素必须是同一个类型的
②.可以按照添加进集合中的元素的指定的顺序遍历,像String,包装类等默认按照从小到大的顺序遍历
public void testTreeSet1() {
Set set = new TreeSet();
// 当Person类没有实现Compareable接口时,当向TreeSet中添加Peronzz对象时,报
// ClassCastException
set.add(new Personzz("岑", 22));
set.add(new Personzz("岑1", 23));
set.add(new Personzz("岑2", 24));
set.add(new Personzz("岑3", 24));
for (Object str : set) {
System.out.println(str);
}
}
打印结果
com.TianTianBaby.java.Personzz@62fc
com.TianTianBaby.java.Personzz@b3c4a
com.TianTianBaby.java.Personzz@b3c6a
com.TianTianBaby.java.Personzz@b3c6b
③.自然排序,当向TreeSet中添加自定义类的对象时,有两种排序方法
自然排序 :要求自定义类实现java.lang.Comparable
接口并且重写Compareable(Object obj)
在此方法中,指明按照自定义类的哪个属性进行排序.
class Personzz implements Comparable {
String name;
Integer age;
public Personzz(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Personzz(String name) {
super();
this.name = name;
}
@Override
public int hashCode() {// return age.hashcode()+name.hashcode(); 没有自带的健壮性好
final int prime = 31;// 质数
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Personzz other = (Personzz) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 当向TreeSet中添加Person类的对象时,依据此方法,确定按照那个属性排列
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
if (o instanceof Personzz) {
Personzz p = (Personzz) o;
// return this.name.compareTo(p.name) ;
// return this.age.compareTo(p.age);
// return -this.age.compareTo(p.age);//倒序
int i = this.age.compareTo(p.age);
if (i == 0) {
return this.name.compareTo(p.name);
} else {
return i;
}
}
return 0;
}
}
总结 : 向TreeSet中添加元素时,首先按照CompareTo
()方法进行比较,一旦返回0,虽然仅是两个对象的属性值相同,但程序会认为这两个对象是相同的,进而后一个对象不能添加进来,所以CompareTo()
与hasCode()
以equals()
三者保持一致!
④.定制排序
无法操作类,Compare()与hashCode()以及equals()三者保持一致
public void testTreeSet2() {
// 1.创建一个实现了Comparater接口的类对象
Comparator com = new Comparator() {
// 向TreeSet中添加Customer类的对象,在此compare()方法中,指明的是按照customer的哪个属性排序的
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Customer && o2 instanceof Customer) {
Customer c1 = (Customer) o1;
Customer c2 = (Customer) o2;
int i = c1.getId().compareTo(c2.getId());
if (i == 0) {
return c1.getName().compareTo(c2.getName());
}
//正序
return 1;
}
return 0;
}
};
// 2.将此对象作为形参传递给TreeSet的构造器中
TreeSet set = new TreeSet(com);
// 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象
set.add(new Customer("AA", 1003));
set.add(new Customer("BB", 1004));
set.add(new Customer("CC", 1005));
set.add(new Customer("DD", 1006));
set.add(new Customer("EE", 1006));
for (Object str : set) {
Customer cus = (Customer)str;
System.out.println(cus.getName());
}
}
打印结果
AA
BB
CC
DD
EE
Customer 类
public class Customer {
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Customer(String name, Integer id) {
super();
this.name = name;
this.id = id;
}
}
匿名方法
public void testTreeSet3() {
// 1.创建一个实现了Comparater接口的类对象
// 2.将此对象作为形参传递给TreeSet的构造器中
TreeSet set = new TreeSet(new Comparator() {
// 向TreeSet中添加Customer类的对象,在此compare()方法中,指明的是按照customer的哪个属性排序的
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Customer && o2 instanceof Customer) {
Customer c1 = (Customer) o1;
Customer c2 = (Customer) o2;
int i = c1.getId().compareTo(c2.getId());
if (i == 0) {
return c1.getName().compareTo(c2.getName());
}
return 1;
}
return 0;
}
});
// 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象
set.add(new Customer("AA", 1003));
set.add(new Customer("BB", 1004));
set.add(new Customer("CC", 1005));
set.add(new Customer("DD", 1006));
set.add(new Customer("EE", 1006));
for (Object str : set) {
System.out.println(str);
}
}
二 : MAP接口
-
HashMap
key
是用set来存放的,不可重复,value
是用Collection来存放的,可重复 一个key-value是一个Entry
,所有的Entry是用Set存放的,也是不可重复的.
向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同,若相同则只能添加进后添加
的那个元素.
public void test1() {
Map map = new HashMap();
//向Map中添加一个元素
map.put("雪芙", 35);
map.put("雨辰", 32);
map.put("代劲", 38);
map.put(null, null);
map.put("雨辰", 35);
map.put(new Personzz("馨日",23), 30);
map.put(new Personzz("馨月",23), 34);
System.out.println(map.size());
System.out.println(map);
//按照指定的key删除key-value对
map.remove("代劲");
//putAll 将一个新的Map中所有元素添加进来
//clear清空
//get获取指定Key的Value值若无此Key 返回null
map.get("雨辰");
}
Map的遍历方法
public void test2() {
Map map = new HashMap();
//向Map中添加一个元素
map.put("雪芙", 35);
map.put("雨辰", 32);
map.put("代劲", 38);
map.put(null, null);
}
LinkedHashMap 与 HashMap操作一样
public void test3() {
Map map = new LinkedHashMap();
//向Map中添加一个元素
map.put("雪芙", 35);
map.put("雨辰", 32);
map.put("代劲", 38);
map.put(null, null);
map.put(new Personzz("馨日",23), 30);
Set set1 = map.keySet();
for(Object obj:set1) {
System.out.println(obj+"--->>>"+map.get(obj));
}
}
- 遍历key集
Set set = map.keySet();
for(Object obj : set) {
System.out.println(obj);
}
打印结果
null
代劲
雨辰
雪芙
- 遍历value集
Collection values = map.values();
Iterator i = values.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
打印结果
null
38
32
35
- 遍历Key-value对
方式一
Set set1 = map.keySet();
for(Object obj:set1) {
System.out.println(obj+"--->>>"+map.get(obj));
}
打印
null--->>>null
代劲--->>>38
雨辰--->>>32
雪芙--->>>35
方式二
Set set2 = map.entrySet();
for(Object obj:set2) {
Map.Entry entry = (Map.Entry)obj;
System.out.println(entry.getKey()+"----->"+entry.getValue());
System.out.println(entry);
}
打印
null----->null
null=null
代劲----->38
代劲=38
雨辰----->32
雨辰=32
雪芙----->35
雪芙=35
TreeMap 自然排序 与TreeSet方法相同
public void test4() {
Map map = new TreeMap();
//向Map中添加一个元素
map.put(new Personzz("aa",23), 30);
map.put(new Personzz("bb",22), 30);
map.put(new Personzz("cc",21), 30);
map.put(new Personzz("dd",21), 30);
Set set1 = map.keySet();
for(Object obj:set1) {
System.out.println(obj+"--->>>"+map.get(obj));
}
}
TreeMap 定制排序
public void test5() {
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Customer && o2 instanceof Customer) {
Customer c1 = (Customer) o1;
Customer c2 = (Customer) o2;
int i = c1.getId().compareTo(c2.getId());
if (i == 0) {
return c1.getName().compareTo(c2.getName());
}
return 1;
}
return 0;
}
};
TreeMap map = new TreeMap(com);
map.put(new Customer("aa" , 1001), 80);
map.put(new Customer("bb", 1002), 81);
map.put(new Customer("cc", 1003), 82);
map.put(new Customer("dd", 1004), 83);
Set set1 = map.keySet();
for(Object obj:set1) {
System.out.println(obj+"--->>>"+map.get(obj));
}
}
使用properties处理属性文件
public void test6() throws FileNotFoundException, IOException {
Properties pros = new Properties();
pros.load(new FileInputStream(new File("jdbc.properties")));
String str = pros.getProperty("user");
String password = pros.getProperty("password");
System.out.println(str);
System.out.println(password);
}
Enumeration接口
Enumeration 接口是Iterator迭代器的古老版本
public class TestEnumeration {
public static void main(String[] args) {
Enumeration enu = new StringTokenizer("ab-c*-df-g","-");
while(enu.hasMoreElements()) {
System.out.println(enu.nextElement());
}
}
}
打印
ab
c*
df
g
四 : Collections
操作Collection
以及Map
的工具类
使用方法
public void testCollections1() {
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(789);
list.add(15);
System.out.println(list);
//反转
Collections.reverse(list);
System.out.println(list);
//随机排序
Collections.shuffle(list);
//根据元素的自然排序指定List集合元素按升序排序
Collections.sort(list);
//根据指定的Compartor产生的顺序对List集合元素进行排序
// Collections.sort(list, c);
//swap(List,int i,int j)将指定List集合中的i处元素和j处元素进行交换
Collections.swap(list, 0, 3);
}
public void testCollections2() {
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(789);
list.add(15);
Collections.max(list);
Collections.min(list);
//返回指定集合中指定元素的出现次数
int count = Collections.frequency(list, 15);
System.out.println(count);
//实现List的复制
//void copy(List dest,list src)将src中的内容复制到desc中
// List list1 = new ArrayList();//错误的实现方式
List list1 = Arrays.asList(new Object[list.size()]);
Collections.copy(list1, list);
System.out.println(list1);
//boolean replaceAll(List list,object oldVal ,object newVal)
//使用新值替换List旧值
//线程安全的 该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时
//的线程安全问题
List list2 = Collections.synchronizedList(list);
System.out.println(list2);
}