page contents

Python与Java的区别:从基础数据类型和数据结构上来看

由于面试经常被cue使用Python和Java两种语言,到底有什么区别,从基础数据类型、数据结构几方面整理下他们的区别。

attachments-2021-04-yurREmcH60867b5ea9d1c.png

由于面试经常被cue使用Python和Java两种语言,到底有什么区别,从基础数据类型、数据结构几方面整理下他们的区别。

Python的基本数据类型与数据结构

一、基础数据类型

  标准数据类型:

    ·不可变数据类型(当值改变时,会产生新的id编号)

      Number(数字):int、float、bool、complex(复数)

      String(字符串)

      Tuple(元祖):不可变,无法通过下标来修改值

    ·可变数据类型(当值改变时,id编号不变化【可以使用id()函数来查看】)

      List(列表):[ ]

      Set(集合):{ }  

      Dictionary(字典):{ key:value}

二、基本数据结构(列表、集合、字典、元祖):

  • 列表:list = [val1, val2, val3, val4],用中括号;
  • 元组:tuple = (val1, val2, val3, val4),用小括号;
  • 字典:dict = {key1: val1, key2: val2, key3: val3},用大括号;
  • 集合:set = {val1, val2, val3, val4},用大括号;

1.列表
list = [val1, val2, val3, val4],列表最显著的特征是:

  • 列表中每个元素都是可变的;
  • 列表中元素是有序的,即每个元素都有一个位置;
  • 列表可以容纳Python的任何对象;

接下来看列表的增删改查:
增:

  1. or_list = [1, "abc", 2.51]
  2. or_list.append("JavaScript") # append()方法在列表末尾追加元素(以整体形式追加)
  3. or_list.insert(0, "Python")
  4. print("or_list is: ", or_list)

用insert()方法可以实现在列表中增加元素。insert()方法需要写明增加在哪个位置和增加的内容,新元素的实际位置是在指定位置元素之前的位置;如果指定的位置不存在,默认会增加在列表末尾;

  1. or_list = [1, "abc", 2.51]
  2. or_list[0:0] = [9] # [0:0]是指在列表中的第1个位置插入新元素
  3. or_list[3:3] = "a" # [3:3]是指在列表中的第4个位置插入新元素
  4. print("or_list is: ", or_list)

上面的这两种方法都是天价单个元素,除了添加单个元素,还可以添加多个元素,用extend()方法来实现:

  1. or_list = [1, "abc", 2.51]
  2. ex_list = ["Python", 23, "game"]
  3. or_list.extend(ex_list) # extend()方法用于在列表末尾一次性追加另一个列表的多个值
  4. print("or_list is: ", or_list)

删:

  1. or_list = [1, "abc", 2.51]
  2. or_list.remove(1)
  3. print("or_list is: ", or_list)

删除列表元素除了remove()方法外,也可以用del关键字来声明:

  1. del or_list[0:2] # [0:2]删除第1个和第2个位置元素
  2. print("or_list is: ", or_list)

改:

  1. lst = [1, "abc", 2.51]
  2. lst[0] = "start"
  3. lst[2] = 777
  4. print("lst is: ", lst)

如果想要替换掉列表中的某个元素,可以直接给列表某位置的元素重新赋值,lst[2]指lst列表中的第3个元素;
查:
列表的索引与字符串的索引类似,同样是分正反两种索引方式,可以从后往前,也可以从前往后所以,比如:

  1. src_list = [1, "abc", 2.51]
  2. # 输出第2个位置和倒数第1个位置的元素
  3. print(src_list[1], src_list[-1])
  4. # 输出第1、2个元素和第2到最后一个元素
  5. print(src_list[:2], src_list[1:])

但是如果想查看某个元素的位置,就需要使用下面这种方式:

  1. src_list = [1, "abc", 2.5, 360]
  2. print(src_list.index(2.5))

这里需要注意的是,如果index()查找的元素不在列表里面,程序会产生ValueError:"xxx" is not in list

2.元组
tuple = (val1,val2,val3,val4),Python中的元组与列表类似,不同之处在于元组不可修改,类似于稳定版的列表,因此在列表中可以使用的增删改的方法在元组中是不可以使用的,但是可以对元组中的元素进行索引,和列表类似。

  1. tup = (1, 2.5, "hello", 26, "abc")
  2. print(tup[0])
  3. print(tup[1])
  4. print(tup[2])
  5. print(tup.index(26))
  6. print(tup.index("hello"))

同样的,index()方法查找的元素不在元组中时,会产生ValueError异常。

3.字典
dict = {key1:val1,key2:val2},编程世界中的很多概念都源自于生活,字典也是。这种数据结构如我们使用的字典一样,通过"名称->内容"来构建,在Python中每个元素都是带有冒号的kye与value的对应关系,习惯称之为键值对。字典的特征如下:

  • 字典中的元素必须时键值对的形式;
  • 键(key)不可以重复,而值(value)可以重复;
  • 键不可变,无法修改;值可以修改,可以是任何对象;

即使字典中有重复的键,输出时也只会出现一次,比如:

  1. d = {"A": "art", "B": "blog", "C": "ascii", "C": "cute", "C": "Java"}
  2. print(d) # {'A': 'art', 'C': 'Java', 'B': 'blog'}

接下来看字典的增删改查:
增:
字典中没有像列表那样的insert()方法,但是可以通过下面这种方式插入元素,元素默认插入在最后一个位置。

  1. d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
  2. d["D"] = "dictionary"
  3. print(d)

再列表中可以通过extend()方法来为列表增加多个元素,在字典中可以使用update()方法来实现添加多个元素;

  1. d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
  2. d.update({"D": "dictionary", "E": "example"})
  3. print(d)

删:
在字典中删除某个元素,也可以使用del关键字:

  1. d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
  2. del d["A"]
  3. print(d)

需要注意的是,虽然字典是用大括号,但删除时依然使用中括号。

改:
如果要修改字典里的元素,直接重新给键赋值即可:

  1. d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
  2. d["B"] = "beyond"
  3. print(d)

查:
在字典中进行查询时,跟删除一样需要通过字典的键来,也就是说对字典的查询和删除都是通过键来的:

  1. d = {'A': 'art', 'B': 'Java', 'C': 'blog'}
  2. d["B"]
  3. print(d["B"])

4.集合
set = {val1,val2,val3,val4},集合的概念有点接近数学上的集合。每个集合中的元素时无序的、不重复的任何Python对象,我们可以通过集合去判断数据的从属关系,有时还可以通过集合把数据结构中重复的元素过滤掉。集合不可以被切片也不能被索引,除了做集合运算外,集合元素可以被添加和删除。

  1. s = {9, 3, 4, 6, 4, 2, 8}
  2. s.add(5) # 新增元素5
  3. s.discard(4) # 删除元素4
  4. print(s) # 输出的集合会从小到大排列,并取重:{2, 3, 5, 6, 8, 9}

Java的基本数据类型和数据结构 

一、基本数据类型

attachments-2021-04-t27TCClN60867ab72d125.png

二、基本数据结构(数组、链表、栈、队列、二叉树、堆、散列表、图)

1.数组(一维数组、多维数组):
优点:内存空间连续,查询快,相对其他结构消耗内存空间小
缺点:初始化时就需要分配数组(内存)大小,不支持动态扩充,插入和删除慢

数组声明后会便会在连续内存空间中进行内存分配,并赋初始值

  1. //此时,int[1] = 0
  2. int[] array = new int[3];

2.链表:内存空间不连续,插入删除快,查询慢
单向链表,双向链表,循环单向链表,循环双向链表

  1. //一种双向链表的实现
  2. public class DoublePointLinkedList {
  3.     private Node head;//头节点
  4.     private Node tail;//尾节点
  5.     private int size;//节点的个数
  6.     
  7.     private class Node{
  8.         private Object data;
  9.         private Node next;
  10.         
  11.         public Node(Object data){
  12.             this.data = data;
  13.         }
  14.     }
  15.     
  16.     public DoublePointLinkedList(){
  17.         size = 0;
  18.         head = null;
  19.         tail = null;
  20.     }
  21.     
  22.     //链表头新增节点
  23.     public void addHead(Object data){
  24.         Node node = new Node(data);
  25.         if(size == 0){//如果链表为空,那么头节点和尾节点都是该新增节点
  26.             head = node;
  27.             tail = node;
  28.             size++;
  29.         }else{
  30.             node.next = head;
  31.             head = node;
  32.             size++;
  33.         }
  34.     }
  35.     
  36.     //链表尾新增节点
  37.     public void addTail(Object data){
  38.         Node node = new Node(data);
  39.         if(size == 0){//如果链表为空,那么头节点和尾节点都是该新增节点
  40.             head = node;
  41.             tail = node;
  42.             size++;
  43.         }else{
  44.             tail.next = node;
  45.             tail = node;
  46.             size++;
  47.         }
  48.     }
  49.     
  50.     //删除头部节点,成功返回true,失败返回false
  51.     public boolean deleteHead(){
  52.         if(size == 0){//当前链表节点数为0
  53.             return false;
  54.         }
  55.         if(head.next == null){//当前链表节点数为1
  56.             head = null;
  57.             tail = null;
  58.         }else{
  59.             head = head.next;
  60.         }
  61.         size--;
  62.         return true;
  63.     }
  64.     //判断是否为空
  65.     public boolean isEmpty(){
  66.         return (size ==0);
  67.     }
  68.     //获得链表的节点个数
  69.     public int getSize(){
  70.         return size;
  71.     }
  72.    
  73. }

3.栈:后进先出,栈顶可操作,栈底不可操作,不允许对栈中指定位置做增删操作。

  1. public class SqStack<T> {
  2. private T data[];//用数组表示栈元素
  3. private int maxSize;//栈空间大小(常量)
  4. private int top;//栈顶指针(指向栈顶元素)
  5. @SuppressWarnings("unchecked")
  6. public SqStack(int maxSize){
  7. this.maxSize = maxSize;
  8. this.data = (T[]) new Object[maxSize];//泛型数组不能直接new创建,需要使用Object来创建(其实一开始也可以直接使用Object来代替泛型)
  9. this.top = -1;//有的书中使用0,但这样会占用一个内存
  10. }
  11. //判断栈是否为空
  12. public boolean isNull(){
  13. boolean flag = this.top<=-1?true:false;
  14. return flag;
  15. }
  16. //判断是否栈满
  17. public boolean isFull(){
  18. boolean flag = this.top==this.maxSize-1?true:false;
  19. return flag;
  20. }
  21. //压栈
  22. public boolean push(T vaule){
  23. if(isFull()){
  24. //栈满
  25. return false;
  26. }else{
  27. data[++top] = vaule;//栈顶指针加1并赋值
  28. return true;
  29. }
  30. }
  31. //弹栈
  32. public T pop(){
  33. if(isNull()){
  34. //栈为空
  35. return null;
  36. }else{
  37. T value = data[top];//取出栈顶元素
  38. --top;//栈顶指针-1
  39. return value;
  40. }
  41. }
  42. }

4.队列:先进先出。

  1. public class SqQueue<T>{
  2. private T[] datas;//使用数组作为队列的容器
  3. private int maxSize;//队列的容量
  4. private int front;//头指针
  5. private int rear;//尾指针
  6. //初始化队列
  7. public SqQueue(int maxSize){
  8. if(maxSize<1){
  9. maxSize = 1;
  10. }
  11. this.maxSize = maxSize;
  12. this.front = 0;
  13. this.rear = 0;
  14. this.datas = (T[])new Object[this.maxSize];
  15. }
  16. //两个状态:队空&队满
  17. public boolean isNull(){
  18. if(this.front == this.rear)
  19. return true;
  20. else
  21. return false;
  22. }
  23. public boolean isFull(){
  24. if((rear+1)%this.maxSize==front)
  25. return true;
  26. else
  27. return false;
  28. }
  29. //初始化队列
  30. public void initQueue(){
  31. this.front = 0;
  32. this.front = 0;
  33. }
  34. //两个操作:进队&出队
  35. public boolean push(T data){
  36. if(isFull())
  37. return false;//队满则无法进队
  38. else{
  39. datas[rear] = data;//进队
  40. rear = (rear+1) % maxSize;//队尾指针+1.
  41. return true;
  42. }
  43. }
  44. public T pop(){
  45. if(isNull())
  46. return null;//对空无法出队
  47. else{
  48. T popData = datas[front++];//出队
  49. front = (front+1) % maxSize;//队头指针+1
  50. return popData;
  51. }
  52. }
  53. //get()
  54. public T[] getDatas() {
  55. return datas;
  56. }
  57. public int getMaxSize() {
  58. return maxSize;
  59. }
  60. public int getFront() {
  61. return front;
  62. }
  63. public int getRear() {
  64. return rear;
  65. }
  66. }

5.二叉树(ps:还有一个红黑树,2-3-4树)

  1. class Node {
  2. int value;
  3. Node leftChild;
  4. Node rightChild;
  5. Node(int value) {
  6. this.value = value;
  7. }
  8. public void display() {
  9. System.out.print(this.value + "\t");
  10. }
  11. @Override
  12. public String toString() {
  13. // TODO Auto-generated method stub
  14. return String.valueOf(value);
  15. }
  16. }
  1. class BinaryTree {
  2. private Node root = null;
  3. BinaryTree(int value) {
  4. root = new Node(value);
  5. root.leftChild = null;
  6. root.rightChild = null;
  7. }
  8. public Node findKey(int value) {} //查找
  9. public String insert(int value) {} //插入
  10. public void inOrderTraverse() {} //中序遍历递归操作
  11. public void inOrderByStack() {} //中序遍历非递归操作
  12. public void preOrderTraverse() {} //前序遍历
  13. public void preOrderByStack() {} //前序遍历非递归操作
  14. public void postOrderTraverse() {} //后序遍历
  15. public void postOrderByStack() {} //后序遍历非递归操作
  16. public int getMinValue() {} //得到最小(大)值
  17. public boolean delete(int value) {} //删除
  18. }

6.堆(底层是完全二叉树,可以实现优先级队列。ps:此堆是一种特殊的二叉树与堆内存不是一个概念)

优先级队列(底层二叉树):最大优先队列(取出的是权值最大的元素)、最小优先队列(取出的是权值最小的元素)
7.Hash表:Hash值相同的对象不一定相同,但是相同的对象Hash值一定相同。线程不安全。

Hash地址的构建

直接取址法:取k 或k 的某个线性函数为Hash地址,这样取的值都不一样,但所需容量庞大
数字分析法:知晓k的数字规律,取产生冲突概率小的的值作为Hash地址
平方取中法:取k值平方数,取该平方数的中间几位,较常用
折叠法:分割k值,做叠加之类的处理
随机数法
PS:Hash函数的构造算法可能导致Hash地址的两个极限,Hash地址都一样则链表非常长,查询性能下降;Hash地址都不一样则HashMap(内部通过数组保存数据)可能会经过多次扩容,容量大增。

JDK Hash冲突的解决办法:JDK1.8之前采用链地址法(即用链表来保存下一个元素);JDK1.8增加了一个策略,使用常量TREEIFY_THRESHOLD(冲突的元素个数超过该常量)来控制是否切换到平衡树来存储。

相关文章:

Python变量作用域(全局变量和局部变量)

Python变量的定义以及使用

Java新手入门常用代码大全,建议收藏并背会!

更多技术资讯,请继续关注六星教育社区-程序员编程技术分享交流学习高端论坛

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-x2WAHlkg62abefec99db0.jpeg

  • 发表于 2021-04-26 16:40
  • 阅读 ( 639 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章