第3阶段 Java高级特性

  • 字节和字符
  • 第2关:字节流 - 输入输出
  • 输入流
  • 输出流
  • 核心就是在使用完流之后,释放它所占用的资源。
  • 第3关:字符流 - 输入输出
  • 第4关:复制文件
  • 文件和代码输入流的区别
  • 第2关:ArrayList集合的增删改查
  • 集合的体系结构
  • 快问快答
  • 第3关:集合的体系结构
  • 第4关:泛型
  • Map集合的特点
  • Java 字符串与集合练习——词频统计
  • String.split()拆分字符串
  • StringTokenizer类拆分字符串
  • 代码
  • 第2关:确定单词在字符串中的位置
  • String.indexOf(String str)
  • String.indexOf(String str, int fromIndex)
  • 代码
  • 第3关:实现词频统计和排序输出
  • 如何进行排序


字节和字符

二级评论java怎么实现分页_数据

第2关:字节流 - 输入输出

输入流

二级评论java怎么实现分页_intellij-idea_02

输出流

二级评论java怎么实现分页_intellij-idea_03

核心就是在使用完流之后,释放它所占用的资源。

OutputStream out = null;  
try {  
    String file = "D://test.txt";  
    out = new FileOutputStream(file);  
    String str = "hello educoder";  
    byte[] b = str.getBytes();  
    out.write(b);  
    out.flush();  
} catch (Exception e) {  
    e.printStackTrace();  
} finally {  
    if (out != null) {  
        try {  
            out.close(); // 释放该输出流  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
package step2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Task {
	
	public void task() throws IOException{
		/********* Begin *********/

		//使用输入流读取src/step2/input/目录下的task.txt文件信息并输出到控制台,
		File file = new File("src/step2/input/task.txt");
		FileInputStream fs = new FileInputStream(file);
		byte[] b = new byte[8];
		fs.read(b);
		String str = new String(b,"UTF-8");
		System.out.println(str);

		//使用输出流将字符串learning practice写入到src/step2/output/目录下的output.txt,若文件目录不存在,则创建该目录。
		File file2 = new File("src/step2/output");  
		file2.mkdir();
		File file3 = new File("src/step2/output/output.txt");  
		file3.createNewFile();
		

		FileOutputStream out = null;  
		try {  
			out = new FileOutputStream(file3);  
			String str2 = "learning practice";  
			byte[] b2 = str2.getBytes();  
			out.write(b2); 
			out.flush();  
		} catch (Exception e) {  
			e.printStackTrace();  
		} finally {  
			if (out != null) {  
				try {  
					out.close(); // 释放该输出流  
				} catch (IOException e) {  
					e.printStackTrace();  
				}  
			}  
		}  
        
		
		/********* End *********/
	}
	
}

第3关:字符流 - 输入输出

二级评论java怎么实现分页_二级评论java怎么实现分页_04


上面代码fw.flush()和fw.close()也可以省略fw.flush(),只写fw.close()就可以了,但是都省略是不对的,如果都省略你会发现文本没有写入到hello.txt文件。

package step3;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Task {
	
	public void task() throws IOException{
		/********* Begin *********/
		String file1 = "src/step3/input/input.txt";   //创建文件
		FileReader fr = new FileReader(file1);   //实例化
		char[] ch = new char[8];  //创建数组
		fr.read(ch);              //将文件的数据读入到数组中(从前到后)

		String file2="src/step3/output/output.txt";//创建文件
        FileWriter fw = new FileWriter(file2); // 实例化
        fw.write(ch); // 读入数组中的数据到文件中(从后到前)

        fr.close();   //关闭流
        fw.flush();   //刷新流
        fw.close();   //关闭流
		/********* End *********/		
	}
}

二级评论java怎么实现分页_二级评论java怎么实现分页_05


字符流只适用于操作字符类型的文件.字节流来操作非字符类文件。

第4关:复制文件

package step4;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Task {
	
	public void task() throws IOException{
		/********* Begin *********/
//复制src/step4/input/目录下的input.txt文件到src/step4/output/目录下,新文件命名为output.txt;
		String file1 = "src/step4/input/input.txt";
		FileReader fr = new FileReader(file1);//定义FileReader读取文件 
		int len = 0;// 每次读取的长度
		char[] cbuf = new char[1024];//每次读取数据的缓冲区

		String file2 = "src/step4/output/output.txt";
		FileWriter fw = new FileWriter(file2); //定义FileWriter写文件  

		while((len = fr.read(cbuf)) != -1){
			fw.write(cbuf,0,len);//将cbuf 0 到len长度的数据添加到builder 
		}
		fw.close();    //释放资源 刷新缓冲区  
		fr.close();  
		
		//字符流只适用于操作字符类型的文件.字节流来操作非字符类文件。
//复制src/step4/input/目录下的input.jpg文件到src/step4/input/目录下,新文件命名为output.jpg		
 		//定义文件输入流读取文件信息  
		FileInputStream fs = new FileInputStream("src/step4/input/input.jpg"); 
		//定义文件输出流写文件
		FileOutputStream fos = new FileOutputStream("src/step4/output/output.jpg");
		int len2 = 0;        //每次读取数据的长度  
		byte[] bys = new byte[1024];    //数据缓冲区
		while( (len2 = fs.read(bys)) != -1){  
			fos.write(bys, 0, len2);  
		}
		//释放资源  刷新缓冲区  
		fs.close();  
		fos.close();
		
		/********* End *********/		
	}
}

文件和代码输入流的区别

文件

FileReader fr = new FileReader(file1);
FileWriter fw = new FileWriter(file2); // 实例化

图片

FileInputStream fs = new FileInputStream("src/step4/input/input.jpg"); 
FileOutputStream fos = new FileOutputStream("src/step4/output/output.jpg");

相同点

都需要释放资源
1、//释放资源  刷新缓冲区  
		fs.close();  
		fos.close();
2、fr.close();   //关闭流
        fw.flush();   //刷新流
        fw.close();   //关闭流

第2关:ArrayList集合的增删改查

package step2;

import java.util.ArrayList;
import java.util.Scanner;

public class HelloWorld {
	
    @SuppressWarnings("unchecked")
	public static void main(String[] args) {
		//获取输入的数据并添加至集合
		Scanner sc = new Scanner(System.in);
		ArrayList list = new ArrayList<>();
        int length = sc.nextInt();
		for(int i =0 ; i< length; i++){
			list.add(sc.next());
			
		}
		//System.out.println(list.toString()); 
		/********** Begin *********/
		//String name = (String)list.get(0);  集合的get()方法获取到数据
		//获取数组的长度
		int l=list.size();
		//System.out.println("集合长度:"+l);
		//删除集合的第一个和最后一个元素;
		list.remove(length-1);
		list.remove(0);
		//System.out.println("删除后集合:"+list.toString());
		//添加两个字符串:hello,educoder至集合中;
		list.add("hello");
		list.add("educoder");
		//System.out.println("加入元素后集合:"+list.toString());
		//修改集合的第三个元素,改为:list;
		list.set(2,"list");
		//输出集合中所有的元素。
		for(int j=0; j<list.size(); j++){
			System.out.println((String)list.get(j));
		}
		
		/********** End **********/
	}
}

集合arraylist 输出时需要用 list.get()

集合的体系结构

Java中的集合分为两大家族,一个是Collection家族,Collection家族有三大成员:List、Queue、Set,这三大成员有三个子类(实际还有很多,这里不一一列举)分别是,ArrayList,LinkedList,HashSet,这个家族有一个特点,那就是他们都是单身,集合中的元素都是独立存在的。

另一个就是Map家族了,这个家族的特点就是他们都是成双成对(key和value)一起出现的

二级评论java怎么实现分页_intellij-idea_06

快问快答

问:Set集合与List集合有什么区别呢?
答:Set集合中的数据不可重复,数据是无序的,List集合的数据可以重复,数据是有序的。

问:就没啦?[严肃脸]
答:哦哦,还有,Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变,List和数组类似
,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,
因为会引起其他元素位置改变。

问:Map集合中的元素可以重复吗?
答:不可以!

问:你说一说,LinkedList和ArrayList的区别吧。
答:好嘞,LinkedList集合增删速度更快,ArrayList改查更快。

问:咳咳咳,下一位!
答:诶诶诶,别呀,我还没说完呢:  

ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。LinkedList是双向链表。
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

第3关:集合的体系结构

package step3;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class HelloWorld {
	
	public HashSet getHashSet(){
		/********** Begin **********/
		
		HashSet set = new HashSet();
		set.add("www.educoder.net");
		return set;

		
		
		
		/********** End **********/
	}
	
	public ArrayList getArrayList(){
		/********** Begin **********/
		List list = new ArrayList();
		list.add("www.educoder.net");
		return list;
		
		
		
		
		/********** End **********/
	}
	
	public LinkedList getLinkedList(){
		/********** Begin **********/
		LinkedList list1 = new LinkedList();
		list1.add("www.educoder.net");
		return list1;
		
		
		
		
		/********** End **********/
	}
	
	public Map getHashMap(){
		/********** Begin **********/
		HashMap map = new HashMap();  
		map.put("address","www.educoder.net"); 
		return map;
		//error: Map is abstract; cannot be instantiated
		//要用HashMap不能用父类Map
		
		/********** End **********/
	}	
	
}

Collection家族用add添加元素,Map家族用put

第4关:泛型

其实泛型也是一样,只不过在这里泛型用在集合上,即指定集合中只能放某一种类型的元素。

ex:你要往ATM机中存钱,就只能放毛爷爷,而不能放冥币,这就是泛型,指定只能用一种类型。

二级评论java怎么实现分页_数据_07

package step4;

import java.util.*;

public class HelloWorld {
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//程序会输入三次数据
		/********** Begin **********/
		//创建一个只能存储String类型数据的List集合;
		List<String> list = new ArrayList<String>();
		
		//将程序输入的数据存入List集合中;
		for(int j=0;j<3;j++){
			list.add(sc.nextLine());
		}
		
		//输出集合中所有的数据。
		for(int i=0; i<list.size(); i++){
			System.out.println("集合的第"+(i+1)+"个数据为:"+list.get(i));
		}
		
		
		
		
		/********** End **********/
	}
	
}

Map集合的特点

有三点需要你记住:

Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够根据key快速查找value;

键(key)值不可重复,值(value)是可以的,通过key可以查找value;

Map支持泛型,形式如:Map<K,V>。

2.删除、修改和获取数据。

Map<String,String> map = new HashMap<String,String>();  
map.put("name","张三");  
map.put("sex","男");
System.out.println("姓名:" + map.get("name") + "性别:" + map.get("sex"));
//修改数据 使用 map.put(key) 方法  
map.put("name","李四");//因为key不能重复,所以修改数据和添加数据使用的同一个方法
System.out.println("姓名:" + map.get("name") + "性别:" + map.get("sex"));
//删除数据 使用 map.remove(key)方法  
map.remove("name");
System.out.println(map.toString());//map.toString方法可以直接输出map集合中的数据

二级评论java怎么实现分页_二级评论java怎么实现分页_08


map.get(“name”)输出key = name时对应的value

package step5;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class HelloWorld {

	public static void main(String[] args) {
		Map<String, Integer> menuDict = new HashMap<>();
		Scanner sc = new Scanner(System.in);
		for (int i = 0; i < 5; i++) {
			menuDict.put(sc.next(),sc.nextInt());
		}
		/********** Begin **********/
		//向menuDict集合中添加一道菜名lamb,它的价格是50;
		menuDict.put("lamb",50);

		//获取menuDict集合中的fish的价格并打印出来;
		System.out.println(menuDict.get("fish"));
		//将menuDict集合中的fish的价格改为100;
		menuDict.put("fish",100);
		//删除menuDict集合中noodles这道菜;
		menuDict.remove("noodles");
		//输出新的menuDict菜单。		
		System.out.println(menuDict.toString());
		
		/********** End **********/
	}
	
}

/因为key不能重复,所以修改数据和添加数据使用的同一个方法

Java 字符串与集合练习——词频统计

String.split()拆分字符串

public class SplitDemo {  
    public static void main(String[] args) {  
        String Str="Harry James Potter";  
        String[] StrArray=Str.split("\\s");//"\\s"表示空格  
        //也可以来" "来进行拆分  String[] StrArray=Str.split(" ");  
        for(String str:StrArray){  
            System.out.println(str);  
        }  
}

StringTokenizer类拆分字符串

import java.util.StringTokenizer;  
public class StringTokenDemo {  
    public static void main(String[] args) {  
        String Str="Harry James Potter";  
        StringTokenizer strToken=new StringTokenizer(Str);  
        //当有拆分的子字符串时,输出这个字符串  
        while(strToken.hasMoreTokens()){  
            System.out.println(strToken.nextToken());  
        }  
    }  
}

代码

package step1;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class StudentDemo{

	//使用String.split()方法分割
	public List<String> splitPartition(String str){
		List<String> list=new ArrayList<String>();
				
//请在此添加实现代码
/********** Begin **********/
		String[] StrArray=str.split("\\|");// "\\"不能少  
        //也可以来" "来进行拆分  String[] StrArray=Str.split(" ");  
        for(String str1:StrArray){  
            list.add(str1);  
        }  
	
/********** End **********/


		return list;
	}

	//使用StringTokenizer类进行分割
	public List<String> tokenPartition(String str){
		List<String> list=new ArrayList<String>();
	//请在此添加实现代码
/********** Begin **********/
		//将字符串按?分隔开,删除?用false。保留分隔符用True
		StringTokenizer strToken=new StringTokenizer(str,"?",false);
		//StringTokenizer是字符串分隔解析类型,属于:java.util包。
		//当有拆分的子字符串时,输出这个字符串  
        while(strToken.hasMoreTokens()){  
            list.add(strToken.nextToken());   
        }  

/********** End **********/	
		return list;
	}

}

第2关:确定单词在字符串中的位置

String.indexOf(String str)

返回指定子字符串在此字符串中第一次出现处的索引。(若返回-1则表示在该字符串中没有你要找的单词)

//声明一段字符串  
String str="Can I help you";  
//显示“I”在str中第一次出现的下标  
System.out.println(str.indexOf("I"));
//String.indexOf(int ch)方法与此方法形同,只是参数是单个字符的ASCII码 (含空格)

String.indexOf(String str, int fromIndex)

返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。  

String str="Can I help you";  
System.out.println(str.indexOf("I",5));
//同样String.indexOf(int ch, int fromIndex)方法与此方法也形同,只是参数是单个字符的ASCII码  
输出:-1

代码

package step2;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
public class StudentDemo{
	//返回一个Map集合来得到单词和首次出现的下标  key为单词名称  value为单词的角标
	public Map<String, Integer> getMap(String str){
		Map<String, Integer> map = new HashMap<String, Integer>();
		//对str进行分割   再加入map集合中
		//请在此添加实现代码
/********** Begin **********/

		List<String> list=new ArrayList<String>();
		StringTokenizer strToken=new StringTokenizer(str," .?,!:",false);
		//StringTokenizer是字符串分隔解析类型,属于:java.util包。
		//当有拆分的子字符串时,输出这个字符串  
        while(strToken.hasMoreTokens()){  
            list.add(strToken.nextToken());   
        }  

		for(int i=0; i<list.size(); i++){
			String key = list.get(i);
			int value = str.indexOf(key);
			map.put(key,value);
		}
	
/********** End **********/
		return map;
	}

}

二级评论java怎么实现分页_java_09


**❥split不行

第3关:实现词频统计和排序输出

package step3;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
public class StudentDemo{
	//获取单词的数量
	public Map<String, Integer> getWordCount(String str) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		
//请在此添加实现代码
/********** Begin **********/
//将指定文本(可以通过右侧文件目录下的src/step3/readme.txt查看)以降序的方式输出每个单词出现的次数。
	//分词存储
		StringTokenizer strToken=new StringTokenizer(str," ,?.!:;\"\"‘’\n",false);
		//StringTokenizer是字符串分隔解析类型,属于:java.util包。
		//当有拆分的子字符串时,输出这个字符串  
		int count;
		String word;
        while(strToken.hasMoreTokens()){  
            word = strToken.nextToken();   
        
			if(map.containsKey(word)){  
			//拿到之前存在map集合中该单词的次数  
				count=map.get(word);  
				map.put(word, count+1);  
			}else{  
				map.put(word, 1);  
			}
		}   

/********** End **********/
		return map;
	}
}

如何进行排序

使用Collections包装类。它包含有各种有关集合操作的静态多态方法。

//可根据指定比较器产生的顺序对指定列表进行排序。
 Collections.sort(List list, Comparator<? super T> c)
//以上实例中的map集合为例   将map集合的每一项添加进list集合中  
List<Map.Entry<String, Integer>> infos = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());  
Collections.sort(infos, new Comparator<Map.Entry<String, Integer>>() {  
    public int compare(Map.Entry<String, Integer> o1,  
        Map.Entry<String, Integer> o2) {  
        //前者-后者  升序         后者-前者  降序  
        return (o2.getValue() - o1.getValue());  
    }  
});