集合
package Chapter1_collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 学习集合的目标:
1.会使用集合存储数据
2.会遍历集合,把数据取出来
3.掌握每种集合的特性
*集合框架学习方式:
* 1.学习顶层接口,抽象类中共性的方法,所有子类/实现类都可以使用
* 2.使用底层,顶层是接口/抽象类,无法创建对象使用,需要使用底层的子类创建对象使用
*
* @author ann
*
*/
public class Fuxi {
/**
* Collection
* 一.共性方法:public boolean add(),remove(),contains(),isEmpty()
* public int size()
* public Object[] toArray():把集合中的元素存在数组中
* public void clear()清空集合不删除集合
*
* 二.遍历:迭代器Iterator接口
* 迭代:先判断集合中是否还有元素,有则取出,,直到所有元素都取出
* 集合中的类获取迭代器:public Iterator iterator();
* 方法:public boolean hasNext() 判断是否有下一个元素
* public E next() 返回迭代的下一个元素
*
* 使用迭代器的步骤:
* 1.利用集合中的iterator()方法获取,用Iterator接口接收,
* 2.使用iterator接口对象的方法hasNext判断集合中是否还有元素,有则用next()取出
*
*三.增强for循环,底层用的就是迭代器
*格式:
* for(集合/数组的数据类型 变量名:集合/数组)
* sout(变量名);
*
*四.泛型
*
*/
/**
* Map集合:双列集合,Collection集合是单列集合
* Map<K,V>,一个key只能映射到一个value,key和value一一对应
* key和value的数据类型可以不同
* 集合中key不可以重复,value可以重复
* key存在再put,新的value会将原来的value覆盖
*
* Map的实现类:HashMap
*/
public static void main(String[] args) {
/**
* Collection 共性方法使用
*/
System.out.println("Collection共性方法使用 "+"---------------------");
Collection<String> c=new ArrayList<String>();
c.add("jkad");
c.add("ksdja");
c.add("jsdh:");
c.remove("jsdh:");
System.out.println(c.contains("jsdh:"));
System.out.println(c.contains("jkad"));
System.out.println(c);
System.out.println(c.size());
System.out.println(c.isEmpty());
System.out.println(c.toArray());
for(Object i:c.toArray()) {
System.out.println(i);
}
c.clear();
System.out.println(c);
System.out.println("集合元素遍历通用方法:利用迭代器Iterator"+"---------------------");
/**
* Collection元素遍历:利用迭代器Iterator
*/
c.add("1");
c.add("2");
Iterator<String> it=c.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
/**
* 增强for循环遍历集合(数组)
*/
System.out.println("增强for循环遍历集合"+"---------------------");
for(String i:c) {
System.out.println(i);
}
/**
* 泛型
* 不使用泛型,则集合可以存储任意数据类型的数据,取出的数据默认是Object
*取出元素后要进行强制类型转化为原来的类型,
*相当于将上转型对象强制转化为原来的类型,
*这时要注意可能会出现类型转换异常 ,有的元素不能进行转换,这就是不要泛型的弊端
*用泛型存之前什么类型取出就是什么类型,避免类型转换的麻烦,将运行期异常提升到编译器,但是泛型是什么类型就只能存储什么类型数据
*
* 迭代器跟着集合走,集合不使用泛型则迭代器也不使用
*/
System.out.println("不使用泛型:"+"-------------");
Collection c1=new ArrayList();
c1.add("jaskd:");
c1.add(1);
c1.add('A');
c1.add("jksd");
System.out.println(c1);
/**
*Collection接口的子接口 :List,Set
*List:有序(存元素与取元素顺序一致),带索引(有与索引有关的方法,注意防止索引越界),可以存取重复的元素
*继承了Collection的方法,学习几个带索引的方法:
*add(int index,E e)
*remove(int index)
*索引从0开始
*set(int index,E e)用指定的元素替换索引位置处的元素
*get(int index)取出索引处元素
*
*
*
*
*/
System.out.println("List方法使用"+"------------");
List<Integer> list=new ArrayList<Integer>();
list.add(9);
list.add(2);
list.add(1);
System.out.println(list);
System.out.println(list.get(2));
System.out.println(list.set(0,1));
list.remove(1);
list.add(2,8);
System.out.println(list);
for(int i:list)
System.out.println(i);
/**
* List实现类ArrayList,查询快,增删慢
*/
/**
* Set接口:不包含重复元素,不含索引(和Collection中方法一样)
* Set接口的实现类,HashSet<E>,无序(存取元素的顺序可能不一致),底层哈希表支持,查询速度快
* 哈希值:十进制的整数,逻辑地址——模拟出来的地址不是物理地址
* Object类中有一个方法hashCode()可以获取对象的哈希码值
*/
System.out.println("Set"+"----------------------");
Set<Integer> set=new HashSet<Integer>();
set.add(1);
set.add(1);
set.add(8);
System.out.println(set);
Iterator<Integer> iterator=set.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
for(int i:set)
System.out.println(i);
/**
* Map常用方法
* put(K key,V value)
* get(K key)
* remove(K key)
* containsKey(key)
*/
System.out.println("Map"+"常用方法"+"---------------------------");
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("wy", 1);
map.put("wjk", 2);
map.put("wjk", 3);
map.put("xy", 3);
System.out.println(map);
System.out.println(map.containsKey("wy"));
System.out.println(map.get("xy"));
map.remove("xy");
System.out.println(map);
/**
* Map集合遍历,
* Set<K> keySet():
* 把Map集合中所有的key取出来存储到Set里,可以利用迭代器或增强for循环遍历set
* 利用get()函数可以得到key对应的value
* entrySet()
*/
System.out.println("Map集合遍历"+"-------------------");
Set<String> s=map.keySet();
Iterator<String> itt=s.iterator();
while(itt.hasNext())
{
String k=itt.next();
System.out.println(""+k+","+map.get(k));
}
for(String ss:s)
System.out.println(""+ss+","+map.get(ss));
/**
* HashMap 实现Map接口
* HashMap底层是哈希表查询速度快
*/
}
}
习题
List与ArrayList的区别
List是一个接口,而ArrayList类是继承AbstractList抽象类和实现List接口的一个实现类。
List接口不能直接创建实例对象,但是可以把ArrayList创建的对象的引用赋给List接口声明的接口变量中,如:List list=new ArrayList();
数组和集合的差异
数组是静态的,一旦在内存中被构造出来,这个数组的大小和容量就固定了,无法再调整它的大小,而集合是动态的,大小不固定;
数组存放的类型只能是一种而集合存放的类型可以不只一种;
数组是线性排列的而不同的集合可以有不同的排列方式。
数组也算是集合的一种。
常用集合类的差异
集合按照其存储结构可以分为单列集合Collection和双列集合Map,Collection是单列集合的根接口,用于存储一系列符合某种规则的元素。Map是双列集合的根接口,是一种基于哈希表集合,它内部的元素总是成对存在的,以key-value的形式存在的。
Collection集合两个重要的子接口,List和Set。List集合的特点是元素有序、可重复;Set集合的特点是元素无序并且不可重复。List接口的主要实现类有ArrayList和LinkedList,Set接口的主要实现类有HashSet和TreeSet。
Map集合中每个元素都包含一对键值,并且Key是唯一的,在使用Map集合时可以通过指定的Key找到对应的Value。Map与List最明显的区别是Map存取元素并不需要下表或者索引号,它总是将key和value同时放入集合,取得某个特定元素的时候则需要给定key。Map接口的主要实现类有HashMap和TreeMap。
List基础练习
1)要求用户循环输入,每次输入赋值给一个String类型变量a,当用户输入”end”(大小写无关)的时候循环结束
2)对每次输入先尝试能否转换为整数b,若不能,进一步尝试转换为双精度浮点数b。
3)如果能够转换为整数,则将该整数加入到List中,否则将双精度浮点数加入到List中,否则将字符串直接加入到List中。
4)循环结束后打印List的所有元素,要求每个元素打印输出的格式为”输出第i个类型为x的元素:v”。其中i用实际序号替换,x用实际类型的中文名替换,v用元素实际值替换。
5)打印所有输入的数值(排除其他类型)的最大值、最小值和平均值
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test{
public static boolean isStr2Int(String str){//判断可否转换成整数
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static boolean isStr2Double(String str){//判断可否转换成双精度浮点数
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static void main(String[] args) {
List list = new ArrayList();
while (true) {
Scanner in = new Scanner(System.in);
String a = in.next();
if (a.equalsIgnoreCase("end"))
break;
if(isStr2Int(a))
list.add(Integer.parseInt(a));
else if(isStr2Double(a))
list.add(Double.parseDouble(a));
else
list.add(a);
}
Double sum=0.0;
int count1=0,count2=0,count3=0;
boolean flag=true; //用于判断max,min是否已经重新赋值
double max=0.0,min=0.0;
for(int i=0;i<list.size();i++){
Object value=list.get(i);
if(value instanceof Integer){
int x=(int)value; count1++;
if(flag) {max=x;min=x;flag=false;}
System.out.println("输出第"+count1+"个类型为整型的元素:"+x);
sum+=x;
if(!flag){
if(max<(double) x)
max=x;
if(min>(double) x)
min=x;
}
}
else if(value instanceof Double){
double y=(double)value; count2++;
if(flag) {max=y;min=y;flag=false;}
System.out.println("输出第"+count2+"个类型为双精度浮点型的元素:"+y);
sum+=y;
if(!flag){
if(max<(double) y)
max=y;
if(min>(double) y)
min=y;
}
}
else{
String z=(String)value; count3++;
System.out.println("输出第"+count3+"个类型为字符串的元素:"+z);
}
}
if(flag)
System.out.println("无数值输入");
else {
double average = sum / (count1 + count2);
System.out.println("最大值:" + max + ",最小值:" + min + ",平均值:" + average);
}
}
}
易错知识
将变量添入集合中,未通过集合改变变量,不影响集合存储的变量。集合中存储的都是引用
泛型限定的是父类类型,泛型类型为T,则T类型及其子类类型变量可以填入集合。
package FUXI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class A{
int x;
}
public class TT {
public static void main(String[] args) {
List<A> list=new ArrayList<A>();
A a=new A(); a.x=921;
A b=new A(); b.x=118;
list.add(a);
list.add(b);
System.out.println("----------");
//改变引用a,b但不改变集合中的引用变量,集合中的引用变量不因为集合外改变而改变,但是通过引用改变对象的变量,则集合存储的引用变量指向的对象的变量自然也发生了改变
b=(A)list.get(0);
a=new A();
a.x=30;
System.out.println(a.x);
System.out.println(b.x);
for(A t:list) {
System.out.println(((A)t).x);
}
a=(A)list.get(0);
b=(A)list.get(1);
System.out.println("-------");
System.out.println(a.x+","+b.x);
a.x=1;
b.x=2;
Iterator it=list.iterator();
while(it.hasNext()) {
System.out.println(((A)it.next()).x);
}
System.out.println("---------------");
List<Integer> l=new ArrayList<Integer>();
int y=1;
int z=4;
l.add(y);
l.add(z);
y=3;
z=9;
System.out.println(y+","+z);
System.out.println("---------------");
for(int i:l)
System.out.println((int)i);
}
}
词频统计
package FUXI;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TT {
public static void main(String[] args) throws IOException {
BufferedReader read=null;
try {
read=new BufferedReader(new FileReader(new File("C:\\Users\\ann\\Desktop\\word.txt")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Map<String,Integer> map=new HashMap<String,Integer>();
String temp=null;
while((temp=read.readLine())!=null) {
String[] s=temp.split("\\s+");
for(String i:s) {
if(map.containsKey(i)) {
map.put(i,map.get(i)+1);
}
else
map.put(i, 1);
}
}
Set<String> set=map.keySet();
for(String i:set) {
System.out.println(i+":"+map.get(i));
}
//System.out.println(map);
}
}