JCF与数据结构

it2024-11-11  5

JCF与数据结构

数组

数组是一个存放多个数据结构的容器

数据是统一类型的所有数据都是线性规则排序的可通过为止索引来进行快速定位访问数据记得明确给出容器的长度

数组的初始化

动态初始化

//数组类型[] 数组名 = new 数据类型[数组长度]; public class Study02{ public static void main(String[] args){ int[] arrays = new int[5]; //定义并开辟了一个长度为3的数组 // 可以将上面代码分成两句来写 int[] array = null; // 声明一个长度int[]类型的变量,变量会占用一块内存空间,它没有分配初始值。 array = new int[5]; //创建一个长度为5的数组,将数组的地址赋给变量arrays。 for(int i = 0; i < arrays.length; i++) { System.out.println("arrays[" + i + "] = " + arrays[i] + " "); } arrays[0] = 10; //数组的第一个元素 arrays[1] = 20; //数组的第二个元素 // 数组遍历 for(int x : array) { System.out.println(array[x]); } } }

静态初始化

//简化格式: //数据类型[] 数组名称 = {值, 值, …}; //完整格式(推荐): //数据类型[] 数组名称 = new 数据类型[]{值, 值, …}; int[] arrays = {1, 2, 3, 4, 5}; int[] arrays = new int[]{1, 2, 3, 4, 5};

注意不要访问越界

数组的遍历方法

//两种方法来遍历 for(int i=0;i<_size;++i){ System.out.println(d[i]); } for(int e :d){ System.out.println(e); }

多维数组

数组的数组Java中多维数组存储是按照行存储原则的 //规则数组 int a[][]=new int[2][3]; //不规则数组 int b[][]; b=new int[3][]; b[0]=new int[3]; b[1]=new int[4]; b[2]=new int[5]; //遍历 //1.根据下标和length属性来遍历 int k=0; for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ a[i][j]=++k; } } //2.根据无索引的方式进行遍历 for(int[] items:a){ for(int item:items){ System.out.println(item+", "); } }

JCF

简介

容器:能够存放数据的空间结构 数组、多维数组,只能线性存放列表/散列集(Hashing)/树(Tree)/… 容器框架:为了表示和操作容器而规定的一种标准体系结构 对外的接口:容器中所能存放的抽象数据类型接口的实现:可复用的数据结构算法:对数据的一系列操作,如查找,排序 JCF的优点:提高数据存放的效率,减少程序员的工作量容器框架两个成功的实例:C++的STL,Java的JCF

主要的数据结构和实现类

列表(List,ArrayList,LinkedList)集合(Set,HashSet,TreeSet,LinkedHashSet)映射(Map,HashMap,TreeMap,LinkedHashMap)
主要算法类

Arrays:对数组进行排序查找等

Collection:对Collection及其子类进行排序查找等

列表List

有序的Collection允许重复的元素

主要实现:

List的主要实现特性ArrayList非同步LinkedList非同步Vector同步

ArrayList

用数组的方式来实现列表,不支持同步

因为为数组,所以不适合进行如插入删除等动态操作但静态操作,如访问效率非常的搞与Java的数组比起来,这个容量可以动态调整在填满容器时候就会自动扩充容器大小的50%

根据官方文档的描述,在非同步的情况下面,有先使用ArrayList!!!

LinkedList

用 双向链表实现的列表,不支持同步

可别当做栈,队列和双向队列进行操作顺序访问的时候高效,随机访问差,动态操作很高效适用于数据经常变化的

Vector

与ArrayList的实现类似,都是数组实现的,但是Vector是同步的!

Vector同步,因此非常适合在多线程当中使用(多线程简介)以前Vector是Java最早的数据类型,不是JCF当中的,由于性能太差了,在JDK1.2的时候对他进行了重写

code

package MyTest01; import java.util.ArrayList; import java.util.List; public class ListTest01 { public static void main(String[] args) { //list中添加,获取,删除元素 List<String> person=new ArrayList<>(); person.add("jackie"); //索引为0 //.add(e) person.add("peter"); //索引为1 person.add("annie"); //索引为2 person.add("martin"); //索引为3 person.add("marry"); //索引为4 person.remove(3); //.remove(index) person.remove("marry"); //.remove(Object o) String per=""; per=person.get(1); System.out.println(per); .get(index) for (int i = 0; i < person.size(); i++) { System.out.println(person.get(i)); //.get(index) } //list总是否包含某个元素 List<String> fruits=new ArrayList<>(); fruits.add("苹果"); fruits.add("香蕉"); fruits.add("桃子"); //for循环遍历list for (int i = 0; i < fruits.size(); i++) { System.out.println(fruits.get(i)); } String appleString="苹果"; //true or false System.out.println("fruits中是否包含苹果:"+fruits.contains(appleString)); if (fruits.contains(appleString)) { System.out.println("我喜欢吃苹果"); }else { System.out.println("我不开心"); } //list中根据索引将元素数值改变(替换) String a="白龙马", b="沙和尚", c="八戒", d="唐僧", e="悟空"; List<String> people=new ArrayList<>(); people.add(a); people.add(b); people.add(c); people.set(0, d); //.set(index, element) //将d唐僧放到list中索引为0的位置,替换a白龙马 people.add(1, e); //.add(index, element); //将e悟空放到list中索引为1的位置,原来位置的b沙和尚后移一位 //增强for循环遍历list for(String str:people){ System.out.println(str); } //list中查看(判断)元素的索引 List<String> names=new ArrayList<>(); names.add("刘备"); //索引为0 names.add("关羽"); //索引为1 names.add("张飞"); //索引为2 names.add("刘备"); //索引为3 names.add("张飞"); //索引为4 System.out.println(names.indexOf("刘备")); System.out.println(names.lastIndexOf("刘备")); System.out.println(names.indexOf("张飞")); System.out.println(names.lastIndexOf("张飞")); //根据元素索引位置进行的判断 if (names.indexOf("刘备")==0) { System.out.println("刘备在这里"); }else if (names.lastIndexOf("刘备")==3) { System.out.println("刘备在那里"); }else { System.out.println("刘备到底在哪里?"); } //利用list中索引位置重新生成一个新的list(截取集合) List<String> phone=new ArrayList<>(); phone.add("三星"); //索引为0 phone.add("苹果"); //索引为1 phone.add("锤子"); //索引为2 phone.add("华为"); //索引为3 phone.add("小米"); //索引为4 //原list进行遍历 for(String pho:phone){ System.out.println(pho); } //生成新list phone=phone.subList(1, 4); //.subList(fromIndex, toIndex) //利用索引1-4的对象重新生成一个list,但是不包含索引为4的元素,4-1=3 for (int i = 0; i < phone.size(); i++) { // phone.size() 该方法得到list中的元素数的和 System.out.println("新的list包含的元素是"+phone.get(i)); } //对比两个list中的所有元素 //两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象 if (person.equals(fruits)) { System.out.println("两个list中的所有元素相同"); }else { System.out.println("两个list中的所有元素不一样"); } if (person.hashCode()==fruits.hashCode()) { System.out.println("我们相同"); }else { System.out.println("我们不一样"); } //判断list是否为空 //空则返回true,非空则返回false if (person.isEmpty()) { System.out.println("空的"); }else { System.out.println("不是空的"); } //返回Iterator集合对象 System.out.println("返回Iterator集合对象:"+person.iterator()); //将集合转换为字符串 String liString=""; liString=person.toString(); System.out.println("将集合转换为字符串:"+liString); //将集合转换为数组,默认类型 System.out.println("将集合转换为数组:"+person.toArray()); 将集合转换为指定类型(友好的处理) //1.默认类型 List<Object> listsStrings=new ArrayList<>(); for (int i = 0; i < person.size(); i++) { listsStrings.add(person.get(i)); } //2.指定类型 List<StringBuffer> lst=new ArrayList<>(); for(String string:person){ lst.add(StringBuffer(string)); } } private static StringBuffer StringBuffer(String string) { return null; } }

集合Set

性质:

确定性互异性无序性

Java当中的Set接口:

Set接口特点HashSet基于散列函数的集合,无序,不支持同步TreeSet基于树结构的集合,可以排序,不支持同步LinkedHashSet基于散列函数和双向列表的集合,可排序,不支持同步

HashSet

基于HashMap实现的,可以容纳null的元素,不支持同步

想要同步 Set s=Collections.synchronizedSet(new HashSet(...)); add 添加一个元素clear 清除整个HashSetcontains 判断是否包含一个元素remove 删除一个元素size 大小retainAll计算两个集合的交集…

LinkedHashSet

继承HashSet,基于HashMap实现的,可以容纳 null元素

方法和HashSet基本一致通过一个双向链表来维护插入操作

TreeSet

基于TreeMap实现的,不可以容纳null元素,

addclearcontains 判断是否包含一个元素remove,sizecompareTo 方法或者指定Comparator排序

上述的三个接口的元素只能是对象!!!

判断元素的重复

HashSet和LinkedHashSet:

判断两个元素hashCode返回值是否相同若两者hashCode相同,判定equals方法,不同则返回false

TreeSet:

需要元素实现Comparable接口比较两个元素的compareTo方法 public class Dog implements Comparable{ private int size; public Dog(int s){size=s;} //get,set function public int compareTo(Object o){ return size-((Dog)o).getSize(); } }

映射Map

Map映射 数学定义:两个集合之间元素的相应关系一个输入对应到一个输出{1,zhangsan},{Key,Value} K-V对 Java中的Map Hashtable(同步,慢数据量小)HashMap(不支持同步,快,数据量大)Properties(同步,文件形式,数据量小)

HashTable

KV对,都不允许为null同步,多线程安全无序的适合数据量小主要方法: clear,contains/containsValue,containKey,get,put,remove,size

HashMap

KV对,都允许可以是null不同步,多线程安全无序的主要方法: clear,containsValue,containKey,get,put,remove,size

LinkedHashMap

基于双向链表的维持插入顺序

TreeMap

基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出

Properties

继承HashTableKV对保存在文件当中适合数据量少的配置文件继承自HashTable的方法文件加载load方法,写入文件 store方法获取属性setProperty,设置属性setPropert

Summary

HashMap是最常用的映射结构如需排序才会考虑LinkedHashMap和TreeMap存储文件才会用Properties类

遍历方法

类型遍历方法HashTableEntry迭代器,KeySet迭代器,KeyEnumeration迭代器HashMap,LinkedHashMapEntry迭代器,KeySet迭代器TreeMap同上Properties import java.util.*; /** * Authored by Gary on 2020/10/21. **/ public class MapTest { public static void main(String[] args) { Hashtable<Integer, String> hashtable = new Hashtable<>(); hashtable.put(1000,"aa"); hashtable.put(2,"bbb"); hashtable.put(30000, "ccc"); System.out.println(hashtable.contains("ccc")); traverByKeyEnumeration(hashtable); HashMap<Integer, String> hashMap = new HashMap<>(); for (int i=0;i<100000;i++){ hashMap.put(i,"dddd"); } traverseByEntry(hashMap); traverByKeySet(hashMap); } private static void traverseByEntry(HashMap<Integer, String> hashMap) { long startTime=System.nanoTime(); System.out.println("====Entry迭代器迭代============"); Integer key; String value; Iterator<Map.Entry<Integer, String>> iter=hashMap.entrySet().iterator(); while (iter.hasNext()){ Map.Entry<Integer,String> entry=iter.next(); key=entry.getKey(); value=entry.getValue(); } long endTime=System.nanoTime(); long duration=endTime-startTime; System.out.println("Entry: duration"+ duration+ "ns"); } private static void traverByKeySet(HashMap<Integer, String> hashMap) { long startTime=System.nanoTime(); System.out.println("====KeySet迭代器迭代============"); Integer key; String value; Iterator<Integer>iter=hashMap.keySet().iterator(); while(iter.hasNext()){ key=iter.next(); value=hashMap.get(key); } long endTime=System.nanoTime(); long duration=endTime-startTime; System.out.println("Entry: duration"+ duration+ "ns"); } private static void traverByKeyEnumeration(Hashtable<Integer, String> hashtable) { System.out.println("===KeyEnumeration迭代器遍历"); Integer key; String value; Enumeration<Integer>keys=hashtable.keys(); while(keys.hasMoreElements()){ key=keys.nextElement(); value=hashtable.get(key); } } }

true ===KeyEnumeration迭代器遍历 ====Entry迭代器迭代============ Entry: duration32959300ns ====KeySet迭代器迭代============ Entry: duration20722900ns

import java.beans.PropertyDescriptor; import java.io.*; import java.util.Enumeration; import java.util.Properties; /** * Authored by Gary on 2020/10/21. **/ public class PropertiesTest { public static String getValueByKey(String filePath,String key){ Properties pps=new Properties(); try{ InputStream in=new BufferedInputStream(new FileInputStream(filePath)); pps.load(in);//加载所有的kv对 String value=pps.getProperty(key); return value; } catch (Exception e) { e.printStackTrace(); return null; } } //获取Properties的全部信息 public static void getAllProperties(String filePath)throws IOException{ Properties pps=new Properties(); InputStream in=new BufferedInputStream(new FileInputStream(filePath)); pps.load(in); Enumeration en=pps.propertyNames();//等到配置文件的名字 while(en.hasMoreElements()){ String strKey=(String)en.nextElement(); String strValue = pps.getProperty(strKey); } } //写入Properties信息 public static void writeProperties(String filePath,String pKay,String pValue)throws IOException{ File file=new File(filePath); if(!file.exists()){ file.createNewFile(); } Properties pps=new Properties(); InputStream in=new FileInputStream(filePath); //从输入流当中读取kv对 pps.load(in); OutputStream out=new FileOutputStream(filePath); pps.setProperty(pKay, pValue); //写入输出流当中 pps.store(out,"Update"+pKay+"name" ); out.close(); } }

工具类

JCF中的工具类

不存储数据,而是在数据容器上面,实现高效的操作 排序搜索 Arrays类Collections类

Arrays:处理对象是数组

排序 sort/parallelSort查找 binarySearch批量拷贝 copyOf批量赋值 fill等价行比较 equals
code
import java.util.Arrays; import java.util.Random; /** * Authored by Gary on 2020/10/21. **/ public class ArraysTest { public static void main(String[] args) { testSort(); testSearch(); testCopy(); testFill(); testEquality(); } private static void testCopy() { System.out.println("测试复制:"); Random r=new Random(); int []a=new int[10]; for(int i=0;i<a.length;++i){ a[i]=r.nextInt(); } int []b=Arrays.copyOf(a,5); for(int i=0;i<b.length;++i){ System.out.println(b[i]); } } private static void testSort() { Random r=new Random(); int []a=new int[10]; for(int i=0;i<a.length;++i){ a[i]=r.nextInt(); } System.out.println("排序前:"); for (int i=0;i<a.length;++i) System.out.println(a[i]+","); System.out.println(); System.out.println("排序后:"); Arrays.sort(a); for(int i=0;i<a.length;++i){ System.out.println(a[i]+","); } System.out.println(); } private static void testSearch() { Random r=new Random(); int []a =new int[10]; for(int i=0;i<a.length;++i){ a[i]=r.nextInt(); } a[a.length-1]=10000; System.out.println("测试查找:"); System.out.println("10000的位置是:"+Arrays.binarySearch(a, 10000)); } private static void testFill() { System.out.println("测试填充"); int []a=new int[10]; Arrays.fill(a, 100); Arrays.fill(a, 2,8,200);//下标2-8,value:200 System.out.println(a[8]); } private static void testEquality() { System.out.println("测试相等:"); int []a=new int[10]; Arrays.fill(a,100); int []b=new int [10]; Arrays.fill(b, 100); System.out.println(Arrays.equals(a, b)); } }

`排序前: 114850936, 1061178683, -2007848625, -146148069, -2010721281, -1785763393, 1162440788, 1055691072, -859380460, 1051727304,

排序后: -2010721281, -2007848625, -1785763393, -859380460, -146148069, 114850936, 1051727304, 1055691072, 1061178683, 1162440788,

测试查找: 10000的位置是:9 测试复制: 1935907383 -756117661 43141791 1341785256 -681803678 测试填充 100 测试相等: true`

Collections

处理对象是Collection及其子类

排序 对List排序 sort搜索 对List搜索批量赋值 List-fill最大最小元素 max min反序 :将List反序排列 reverse

对象的比较

对象实现Comparable接口 重写compareTo方法 新建 Comparator(适用于对象类不可更改的情况) 重写compare方法 import java.util.*; //以下是学生类Student定义,有点类似C语言的结构体啊!^_^ class Student { public int s_no; public String s_name; public int s_class; } public class compareTest { public static void main(String[] args) { //存放学生类的动态数组的初始化 ArrayList<Student> studentArr = new ArrayList<Student>(); Student s1 = new Student(); s1.s_no = 3; s1.s_name = "a"; s1.s_class = 102; studentArr.add(s1); Student s2 = new Student(); s2.s_no = 2; s2.s_name = "b"; s2.s_class = 101; studentArr.add(s2); Student s3 = new Student(); s3.s_no = 1; s3.s_name = "c"; s3.s_class = 103; studentArr.add(s3); //初始化之后先打印以下这个动态数组 System.out.println("排序前:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } //对于Comparator接口的重写 //这个接口就一个抽象函数,给出的参数与返回值都是定死的。 Collections.sort(studentArr, new Comparator<Object>() { public int compare(Object o1, Object o2) { //你首先设置你要比较的东西 //具体是把参数中的Object强制转换成你要比较的东西,这里是两个Student类 //这里的s1,s2与上面的s1,s2一点关系都没有,只是抽象的前者与后者的关系 Student s1 = (Student) o1; Student s2 = (Student) o2; //如果前者的学号大于后者的学号,就是前者大于后者,返回1系统就会识别是前者大于后者 if (s1.s_no > s2.s_no) { return 1; } //小于同理 if (s1.s_no < s2.s_no) { return -1; } //如果返回0则认为前者与后者相等 return 0; } }); //比较完毕再输出以学号排序之后的结果 System.out.println("按学号排序后:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } //以下是以班级排序的过程 Collections.sort(studentArr, new Comparator<Object>() { public int compare(Object o1, Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; if (s1.s_class > s2.s_class) { return 1; } if (s1.s_class < s2.s_class) { return -1; } return 0; } }); System.out.println("按班级排序后:"); for (int i = 0; i < studentArr.size(); i++) { System.out .println("我是" + studentArr.get(i).s_class + "班的" + studentArr.get(i).s_name + "学号是" + studentArr.get(i).s_no); } } }
最新回复(0)