java 转 go 快速对照表,建议搭配 smart TOC 工具阅读
这个速查表是为了给 高级 Java 工程师 快速熟悉 Golang 语言特性准备的。
语言只是工具,都有各自的优势和不足,在合适的场景用合适的语言
说明:目录中带星号 * 的代表这部分内容是针对于 java 侧来说的,在 golang 领域可能没有此概念
如果有错误的地方欢迎提 PR 或者 issue
java | go |
---|---|
java | go |
---|---|
Maven、Gradle |
Go Modules (go 1.13 设为默认) |
基础数据类型是 CPU 可以直接进行运算的类型
java | go | 占用内存 |
---|---|---|
byte | byte/uint8 | 1 byte |
short | int16 | 2 byte |
int | int/int32/int64 | java 4 byte; go 4/8 byte(Platform dependent) |
long | int64 | 8 byte |
float | float32 | 4 byte |
double | float64 | 8 byte |
char | rune | java 2 byte; go 4 byte |
boolean | bool | 1 byte |
type: 类型
identifier: 标识符、变量名
value: 值
java | go |
---|---|
type identifier;
type identifier = value; |
var identifier type
var identifier type = value
var identifier = value
identifier := value |
java | go |
---|---|
private static int NUM = 0; //int |
const num = 0 |
java | go |
---|---|
for(int i = 0; i < arr.length; i++){
//...
} |
for i := 0; i < len(arr); i++ {
//...
} |
java | go |
---|---|
String s = "abc";
for(int i : s.toCharArray()){
//...
} |
s := "abc"
for i,v := range s {
//...
} |
java | go |
---|---|
int i = 0;
while(i < 10){
//...
} |
i : = 0
for i < 10 {
i++
} |
java | go |
---|---|
int i = 0;
switch(i){
case 1:
System.out.println("1");
case 2:
System.out.println("2");
case 3:
System.out.println("3");
default:
System.out.println("0");
} |
i := 0
switch i {
case 1:
fmt.Println("1")
case 2:
fmt.Println("2")
case 3:
fmt.Println("3")
default:
fmt.Println("0") |
java | go |
---|---|
int[] arr = new int[10];
Arrays.sort(arr);// sort 默认升序 |
arr := [10]int{} // array 非常用
sli := make([]int, 10) // slice
sort.Ints(sli) // sort []int
sort.Slice(sli, func(a, b int) bool { return sli[a] < sli[b] })
sort.SliceStable(sli, func(a, b int) bool { return sli[a] < sli[b] }) // 如果元素相同保持当前位置不变
|
java | go |
---|---|
List<T> list1 = new ArrayList<>();
List<T> list2 = new LinkedList<>(); |
list1 := make([]T, len(xx)); // array list
var list2 list.List // linked list
list2.pushBack()
for e := list2.Front(); e != nil; e=e.Next() {
fmt.Println(e.Value.(xx))
} |
java | go |
---|---|
Map<T,T> map = new HashMap<>();
map.put(T,T);
T t = map.get(T); |
maps := make(map[T]T)
maps[T] = T
x, ok := maps[T]
if ok {
//do somethings...
} |
java | go |
---|---|
Set<T> set = new HashSet<>(); |
type void struct{}
var x void
set := make(map[T]void) |
java | go |
---|---|
Stack<Integer> stack = new Stack<>();
stack.push(1);
if(!stack.isEmpty()){
int top = stack.peek();// inspect
int topEle = stack.pop();// pop
} |
stack := make([]int, 0)
stack = append(stack, 1)
stack = append(stack, 2)
for len(stack) > 0 {
topEle := stack[len(stack)-1] // inspect
fmt.Println("top element is: ", topEle)
stack[len(stack)-1] = "" // 避免内存泄漏
stack = stack[:len(stack)-1] // pop
fmt.Println("current statck size: ", len(stack))
}
stack = append(stack, 3)
fmt.Println(len(stack))
stack = stack[:0] // flush
fmt.Println(len(stack)) |
java | go |
---|---|
Queue queue = new PriorityQueue<String>(10);
queue.add("hello");
queue.add("world");
while (!queue.isEmpty()){
System.out.println(queue.poll());
} |
// using github.com/golang-collections/collections/queue
q := queue.New()
q.Enqueue("hello")
q.Enqueue("world")
for q.Len() > 0 {
fmt.Println(q.Dequeue())
} |
java | go |
---|---|
byte[] bytes = Files.readAllBytes(Paths.get(filePath)); |
f, err := ioutil.ReadFile("file path")//f is []byte |
java | go |
---|---|
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
System.out.println(scanner.next());
} |
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
fmt.Println(input.Text())
} |
java | go |
---|---|
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
System.out.println(scanner.next());
} |
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
fmt.Println(input.Text())
} |
java | go |
---|---|
String[] strs = "a,b,c".split(","); |
// []string
strs := strings.Split("a,b,c", ",") |
java | go |
---|---|
"".startsWith(prefix);
"".endsWith("suffix");//查找后缀 |
var s string
strings.HasPrefix(s, "prefix") |
java | go |
---|---|
"".endsWith("suffix"); |
var s string
strings.HasSuffix(s,"suffix") |
java | go |
---|---|
"".equals(""); |
str1 == str2 |
面向对象是以对象为核心向外拓展的,可以理解为现实环境中的映射。在 java 中表示为 Class,在 golang 中表示为 struct。在设计时会将对象能力通过方法的形式整合在一起并通过权限控制来加强封装,使用接口 interface 来隐式实现多态。
函数是能给调用者返回一些需要的值,可以在任何地方使用
java | go |
---|---|
class Door{
private String size;
public void open(){
System.out.println("door opened");
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
} |
type Door struct {
size string
}
func open(){
fmt.Println("door opened")
}
|
方法是被定义在类内部,能去修改类的属性,注重类的概念
java | go |
---|---|
class Door{
private String size;
public void open(){
System.out.println("door opened");
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
} |
type Door struct {
size string
}
func (door *Door) setSize(){
door.size = "big"
}
func (door *Door) getSize(){
fmt.Println("door size is:",door.size)
}
|
java | go |
---|---|
public static <D> void print(D data){
System.out.println("your data is " + data);
} |
func print[D any](data D) {
fmt.Print("your data is: ", data)
} |
golang 的接口是隐式实现
java | go |
---|---|
public class TestInterface {
public static void main(String[] args) {
System.out.println("light");
CarLight carLight = new CarLight();
carLight.turnOn();
carLight.turnOff();
}
}
interface Light {
void turnOn();
void turnOff();
}
class CarLight implements Light {
@Override
public void turnOn() {
System.out.println("turn on");
}
@Override
public void turnOff() {
System.out.println("turn off");
}
} |
type light interface {
TurnOn()
TurnOff()
}
type CarLight struct{}
func (carLigth CarLight) TurnOn() {
fmt.Println("trun on")
}
func (carLight CarLight) TurnOff() {
fmt.Println("turn off")
}
func main() {
var carLight CarLight
fmt.Println("light")
carLight.TurnOn()
carLight.TurnOff()
} |
java 和 go 都能够通过一定的规则来控制程序的可见性 scope。 可见性由低到高:
java: default>protect>private>public
go: 小写开头(private) > 大写开头(public)
golang 中大小写可以应用到常量、变量、类型、函数、结构体中 举例:
type User struct{...} User 能够被其他包内的代码访问
type user struct{...} user 只能包内访问
java | go |
---|---|
java | go |
---|---|
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void print() {
System.out.println("my name is " + name);
}
}
class Worker extends Person {
private final String job;
public Worker(String name, String job) {
super(name);
this.job = job;
}
@Override
public void print() {
System.out.println("my job is " + job);
}
} |
type Person struct {
Name string
}
func (person *Person) print() {
fmt.Println("my name is ", person.Name)
}
type Worker struct {
Person // 继承父类
Job string // 子类新增
}
// override
func (worker *Worker) print() {
fmt.Println("my job is ", worker.Job)
} |
多态(Polymorphism)是面向对象编程(OOP)中的一个重要概念,它允许不同的类共享相同的接口或基类,并且在运行时表现出不同的行为。
java | go |
---|---|
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.makeSound(); // 运行时调用Dog类的makeSound方法
}
} |
type Animal interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct{}
func (c Cat) Speak() string {
return "Meow!"
}
func main() {
var animal Animal
animal = Dog{}
fmt.Println(animal.Speak()) // 输出: Woof!
animal = Cat{}
fmt.Println(animal.Speak()) // 输出: Meow!
} |
非原子操作,可使用 atomic 进行累加计算
java | go |
---|---|
static int num = 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(100);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 10; j++) {
new Thread(()->{
add(countDownLatch);
}).start();
}
}).start();
}
countDownLatch.await();
System.out.println(num);
}
private static void add(CountDownLatch countDownLatch){
num++;
countDownLatch.countDown();
} |
var num = 0
// 计数器
func main() {
var wg sync.WaitGroup
for i := 0; i < 10000; i++ {
wg.Add(1) // 计数器加 1
go add(&wg)
}
wg.Wait() // 等待计数器归零
fmt.Println(num)
}
func add(wg *sync.WaitGroup) {
num++
wg.Done() // 计数器减 1
} |
java | go |
---|---|
Lock lock = new ReentrantLock();
if(lock.tryLock()){
try{
// do something...
} finally{
lock.unlock();
}
} |
func main() {
var lock sync.Mutex
for i := 0; i < 10000; i++ {
go addByLock(&lock)
}
time.Sleep(10)
fmt.Println(n)
}
func addByLock(lock *sync.Mutex) {
lock.Lock()
n++
lock.Unlock()
} |
java | go |
---|---|
无 |
channel := make(chan string, 1)
go func() {
channel <- "add"
}()
go func() {
val := <-channel
fmt.Println(val)
}()
time.Sleep(time.Second * 2) |
java | go |
---|---|
// jackson api
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(obj); |
user := &user{Name: "ahian", Age: 18}
b, err := json.Marshal(user)
if err != nil {
fmt.Errorf("could not marshal json: %s\n", err)
return
}
fmt.Println(string(b)) |
java | go |
---|---|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String yearMonthDay = simpleDateFormat.format(new Date()); |
now := time.Now() // 当前时间 默认格式:2006-01-02 15:04:05.999999999 -0700 MST
fmt.Println(now)
format := now.Format("2006-01-02 15:04:05") // 格式化 年月日时分秒
fmt.Println(format) |
指对外提供服务的程序,一般是通过 REST 方式访问
java | go |
---|---|
public static void main(String[] args) throws IOException {
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8090), 0);
httpServer.createContext("/", exchange -> {
exchange.getResponseHeaders().add("Content-Type", "text/html; charset=UTF-8");
byte[] resp = "Hello java server".getBytes(StandardCharsets.UTF_8);
exchange.sendResponseHeaders(200, resp.length);
exchange.getResponseBody().write(resp);
exchange.close();
});
httpServer.start();
} |
java | go |
---|---|
|
|