一、编译原理和开发效率
编译速度: C# (约大于等于) JAVA > Python
python的编译原理
前提:python 3.6+
python不会直接编译源码
而是把源码直接扔给解释器,这种方式 使得python非常灵活,让它的开发效率非常高。
它非常适合数据分析、脚步编写和web开发,当然缺点就是它比编译语言慢,因为它是逐行解释的代码的
Java的编译原理
前提:jdk8+
首先java源代码被编译成字节码(.class文件),运行时由jvm(Java虚拟机执行)将其转换成机器码,由于java里面使用JIT(即时编译)在执行之前动态编译关键的字节码,所以Java的运行速度相对比Python快2-4倍。
其次:Java8及以上默认开启了分层编译,一般有client编译器和server编译器,两种编译器混合编译,以达到最高的性能
C#的编译原理
前提:net core 3.0+
由Roslyn(C# 和 Visual Basic)编译器进行编译成IL(也就是中间语言),然后(.netcore clr)运行时会对其进行编译并将其执行。当然.net平台也使用的分层编译的机制对IL进行相关优化。
**开发效率: Python> C# > JAVA **
至于为啥开发效率会是这样,主要是它们的语法灵活性导致的,后面我将对比它们的一些基础语法。
二、常用的数据类型
1.python里常用数据类型
2.java里常用数据类型
3.C#里常用数据类型
讲讲Tuple C#和Python里面有 它是一组类型不同的数据集合(不可变的)
List Set 是在python 、c#、JAVA里面都有的
这个出现了个Dictionary 也就是字典 在JAVA的表现形式略有不同,它用的Map,其实功能都是差不多的 都是存放键值对的
然后我们来看看 python里面 List Set Dictionary 是怎么取值的
在Python和C#里面
List 和 Tuple 使用的索引(下标-index) list.[index] 取值/赋值
Dictionary 使用的索引(key) dict.[key] 取值和赋值在JAVA里面
List 和 Set 使用的索引(下标-index) get(index) 取值和赋值
Dictionary 使用的索引(key) get(key) 取值和赋值
4.小结:
1.Python最灵活,毕竟是弱类型语言,约束性低,当然排查错误很难是它最大的缺点
- 对于List Set Map(Dictionary)来说,Java的init方式设计的并不好
- Java的获取值和设置值,需要使用get()/set()/put(),记忆api并不友好,像python/c#里面它的形式是[index/key],很像我们是掉同一个api
三、foreach循环
python
# Tuple 元组
tuple1 = (123, 10 + 5j, "Hello Python")
# 元组的取值 按索引下标取值(不能修改)
for item in tuple1:
#item = 999
print(item)
# List
list1 = [123, 10 + 5j, "Hello Python"]
# list的取值 按索引下标取值
for item in list1:
print(item)
#Dictionary
#dict1 ={}
dict1 = {"one": 123, "two": 10 + 5j, "three": 123}
#形式一 获取实际值
for key in dict1:
print("%s_%s" % (key, dict1[key]))
# 形式二 =>dict_item
for (key,item) in dict1.items():
print("%s_%s" %(key,item))
# Set
#set1 = {,}
set1 = {123, 10 + 5j, "Hello Python",123}
for item in set1:
print(item)
java
//List
List<String> list = new ArrayList<String>();
list.add("123");
list.add("10 + 5j");
list.add("Hello Python");
for (String s : list) {
System.out.println(s);
}
//Map
Map<String,String> map = new HashMap<>();
map.put("one","123");
map.put("two","10 + 5j");
map.put("three","Hello Python");
Set<Map.Entry<String, String>> entries = map.entrySet();
//Set<String> strings = map.keySet();
for (Map.Entry<String, String> entry : entries) {
System.out.println(entry.getKey()+"_"+entry.getValue());
}
map.forEach((key,value)->{
System.out.println(key+"_"+value);
});
//Set
Set<String> set = new HashSet<>();
set.add("123");
set.add("10 + 5j");
set.add("Hello Python");
for (String s : set) {
System.out.println(s);
}
C#
IEnumerable<int> emum1 = Enumerable.Range(0,10);
foreach (var item in emum1)
{
Console.WriteLine(item);
}
#region
/* Tuple<string, string, string> tuple1
= Tuple.Create("123", " 10 + 5j", "Hello Python");*/
//Tuple Array
//简化的方式
string[] array1 = { "123", " 10 + 5j", "Hello Python" };
foreach (var item in array1)
{
Console.WriteLine(item);
}
#endregion
#region Tuple
/* Tuple<string, string, string> tuple1
= Tuple.Create("123", " 10 + 5j", "Hello Python");*/
//Tuple
//简化的方式
(string, string, string) tuple1 = ("123", " 10 + 5j", "Hello Python");
/* for (int i = 0; i < tuple1.Count; i++)
{
}*/
#endregion
#region List
IList<string> list =
new List<string> { "123", " 10 + 5j", "Hello Python" };
foreach (var item in list)
{
Console.WriteLine(item);
}
#endregion
#region Dictionary
IDictionary<string,string> dict = new Dictionary<string, string> {
{"one","123" },
{"two","10 + 5j" },
{"three","Hello Python" },
};
//KeyValuePair<String,String>
foreach (var item in dict)
{
Console.WriteLine(item.Key+"_"+item.Value);
}
#endregion
#region Set
ISet<string> set = new HashSet<string> {
"123", " 10 + 5j", "Hello Python"
};
foreach (var item in set)
{
Console.WriteLine(item);
}
// Set是无序的 所以不能直接用下标取值
#endregion
四、数据切片
java
//非常简单的切分
//Object[] objs2 = Arrays.copyOf(objs, 3);
//Object[] objs3 = Arrays.copyOfRange(objs, 3,8);
//List<Object> objects = list.subList(1, 4);
Map<String,String> map =new HashMap<>();
map.put("name","Java");
map.put("birth","1991");
Object[] objs = {1, 2, 3, 4, 5, 6, 7,map};
List<Object> list =new ArrayList(Arrays.asList(objs));
List<Object> segData =
list.stream().skip(3).limit(5).collect(Collectors.toList());
//segData = Arrays.stream(objs).skip(3).limit(5)
// .collect(Collectors.toList());
for (Object segDatum : segData) {
System.out.println(segDatum);
}
//物理分页
// BufferedReader bufferedReader = Files.newBufferedReader(Paths.get("D:\\Desktop\\battle内容.txt"));
// bufferedReader.skip(100);
// String read = bufferedReader.readLine();
// System.out.println(read);
//并行流 =》list.parallelStream();
// IntStream objectStream = IntStream.range(0, 200);
// //原始迭代器
// Spliterator originSp = objectStream.spliterator();
// //对半切分
// while (originSp.estimateSize()>1){
// Spliterator sp1 = originSp.trySplit();
// System.out.println("originSp剩余数量:" + originSp.estimateSize());
// }
C#
IList<object> list = new List<object>
{
1, 2, 3, 4, 5, 6, 7,
new Dictionary<string,string>{ { "name" ,"1998" },{ "birth", "1998" } }
};
//使用Linq (比较万能)
IEnumerable<object> enumerable = list.Skip(4).Take(5);
foreach (var item in enumerable)
{
Console.WriteLine(item);
}
//使用Range C#8 (仅对数组有效)
int[] arr = { 13, 12, 39, 81,2 };
var slice1 = arr[1..3];//获取第2项-到第四项(不包括)
var slice2 = arr[1..^2];//截止为len-2 从尾部计算
var slice3 = arr[^1];//获取最后一项
// RuntimeHelpers.GetSubArray(arr, Range.EndAt(3));
foreach (var item in enumerable)
{
Console.WriteLine(item);
}
//使用Span
//Span<int> span = arr.AsSpan().Slice(1, 3);
//var arraySpan = new Span<byte>(list);
// 将日志数据转换为字节数组
byte[] logBytes = File.ReadAllBytes(@"D:\Desktop\battle内容.txt");
// 使用Span处理日志数据
Span<byte> logSpan = new Span<byte>(logBytes);
// 在Span中查找特定关键词
string keyword = "error";
byte[] keywordBytes = Encoding.UTF8.GetBytes(keyword);
int keywordCount = 0;
for (int i = 0; i <= logSpan.Length - keywordBytes.Length; i++)
{
if (logSpan.Slice(i, keywordBytes.Length).SequenceEqual(keywordBytes))
{
keywordCount++;
}
}
Console.WriteLine($"匹配次数:{keywordCount}");
python
## 切片支持 string list set tuple dictionary
var1 = "1,2,3,4,5,6,7,'hello','Python'"
var1 = (1, 2, 3, 4, 5, 6, 7, 'hello', 'Python')
var1 =[1,2,3,4,5,6,7,{"name":"Python","birth":"1989"}]
segeme_var = var1[4:8]
print(segeme_var)
优雅性: Python > C# > Java
(相对)性能: C# > Java > Python
五、对IO流如何关闭
java
//方式一 try-finally (jdk8以前)
BufferedReader bufferedReader1 =null;
try {
bufferedReader1 = Files.newBufferedReader(Paths.get("D:\\Desktop\\battle内容.txt"));
//coding
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bufferedReader1!=null){
try {
bufferedReader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//方式二 try-resource (jdk8+)
try( BufferedReader bufferedReader2 =
Files.newBufferedReader(Paths.get("D:\\Desktop\\battle内容.txt"))) {
//coding
} catch (IOException e) {
e.printStackTrace();
}
C#
//方式一 try-finally
FileStream fileStream1 = null;
try
{
fileStream1 = File.OpenRead("D:\\Desktop\\battle内容.txt");
}
catch (Exception)
{
}
finally
{
fileStream1?.Close();
}
//方式二 using
using ( FileStream fileStream2 = File.OpenRead("D:\\Desktop\\battle内容.txt") )
{
}
python
#!/usr/bin/python3
# -*- coding: utf-8 -*-
fr = None
# region 方式一 try-finally
try:
fr = open("D:\\Desktop\\battle内容.txt", "r")
var1 = 1/0
finally:
if fr is not None:
print("已关闭")
fr.close()
pass
# endregion
# # region 方式二 with
# with open("D:\\Desktop\\battle内容.txt", "r") as fr2:
# var1 = 1/0
# # endregion
六、关于它们的继承不同
java
支持单一继承 多个实现
public class Particle {
//转动
public void turn(){
System.out.println("可以转动");
}
}
public class Wave {
//扩散的
public void diffuse(){
System.out.println("可以扩散");
}
}
//单个继承
public class Light extends Particle{
public static void main(String[] args) {
Light light = new Light();
light.diffuse();
light.turn();
}
}
C#
支持单一继承 多个实现
namespace NetCore_Demo.inherit
{
public class Particle { //粒子
public void Turn() { //转动
System.Console.WriteLine("可以转动");
}
}
public class Wave
{ //波
public void Diffuse(){//扩散的
System.Console.WriteLine("可以扩散");
}
}
public class Light:Wave
{
static void Main(string[] args)
{
Light light = new Light();
light.Diffuse();
}
}
}
python
支持多个继承 无接口实现
class Particle: # 粒子
@classmethod
def turn(self):
print("可以转动")
class Wave: # 波
@classmethod
def diffuse(self):
print("可以扩散")
class Light(Particle,Wave): # 光
pass
if __name__ == '__main__':
light1 = Light()
light1.turn()
light1.diffuse()
七、关于它们的重载不同
java
√1.跟返回值类型无关,只跟参数列表有关
√2.不支持关键字和参数默认值
public class MyOverload {
public void learn(){
System.out.println("正在文化课的学习");
}
public void learn(String course){
System.out.println(String.format("正在%s的学习", course));
}
/**
* @param course 课程名称 举个例子: 舞蹈 跆拳道
* @param learnTime 时间学习时长
* @return 是否完成学习时长
*/
public boolean learn(String course,float learnTime){
float totalTime =3f;
System.out.println(String.format("正在%s的学习,学习时长:%s小时"
, course,learnTime));
return totalTime<=learnTime;
}
public static void main(String[] args) {
MyOverload myOverload =new MyOverload();
myOverload.learn();
myOverload.learn("舞蹈");
bool f = myOverload.learn("舞蹈",1);
System.out.println("是否完成学习任务"+f);
}
}
C#
√1.跟返回值类型无关,只跟参数列表有关
√2.支持关键字和参数默认值
using System;
namespace NetCore_Demo.overload
{
public class MyOverload
{
public void learn()
{
Console.WriteLine("正在文化课的学习");
}
public void learn(string course)
{
Console.WriteLine($"正在{course}的学习");
}
/// <param name="course">课程名称 举个例子: 舞蹈 跆拳道</param>
/// <param name="learnTime">时间学习时长</param>
/// <returns>是否完成学习时长</returns>
public bool learn(string course, float learnTime)
{
float totalTime = 3f;
Console.WriteLine($"正在{course}的学习,学习时长:{learnTime}小时");
return totalTime <= learnTime;
}
static void Main(string[] args)
{
MyOverload myOverload = new MyOverload();
myOverload.learn();
myOverload.learn("舞蹈");
bool f = myOverload.learn("舞蹈", 1);
Console.WriteLine("是否完成学习任务" + f);
// 关键词参数 + 参数默认值
}
}
}
python
√python 在类里面只有覆盖没有重载
class MyOverload:
def learn(self, course="舞蹈", learnTime=3):
print(f"正在{course}的学习,学习时长:{learnTime}小时")
return learnTime >= 3
if __name__ == '__main__':
myOverload = MyOverload()
myOverload.learn()
myOverload.learn(course="跆拳道")
八、函数式接口
1、python是天然的函数式接口
2.c#里面用于委托,这个可以多播,可以实现函数的回调
public delegate void Action();
public delegate void Action<in T1>(T1 arg1);
public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6>
(T1 arg1, T2 arg2, T3 arg3, T3 arg4, T3 arg5, T3 arg6);
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T1, out TResult>(T1 arg1);
...
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5,
in T6, out TResult> (T1 arg1,T2 arg2,T3 arg3,T4 arg4,T5 arg5,T6 arg6)
public delegate bool Predicate<in T>(T obj)
3.java8里面使用函数式接口(@FunctionInterface)
//无返回值类型
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
//......
}
===》BiConsumer<T, U>
//一个入参 一个返回值
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
//......
}
===》BiFunction<T, U, R>
//一个入参 返回值是布尔类型
@FunctionalInterface
public interface Predicate<T> {
//对给定的参数求值
boolean test(T t);
}
===》BiPredicate<T, U>
九、相关视频链接:
https://www.bilibili.com/video/BV1Cw411V78V
https://www.douyin.com/user/self?modal_id=7315770090534882570