Dart入门记录

211 阅读4分钟

前言

本文为笔者一年前对于Dart的基础的一些记录,以后每篇文章尽量最后携带一道算法题,作为练手。

参考资料:

Dart学习笔记

Dart英文文档

Dart2中文文档

目录

区别点

  1. var 变量

    • 字符串串表达式${expression},''' '''引号 '' "区别,==判断对象内容是否一样

      var s = "${s.toUpperCase()} is very ok";
      var s2 = '''
      aaa
      bbb
      ''';
      s2 output->
      aaa
      bbb
      var s3 = r"this is \n";
      s3 output->
      this is \n
      
  2. 内置变量num (int double) bool const 编译时

  3. bool类型

    var name = 'Bob';
    if(name){
        print('You hava a name!');
    }
    JS中结果:(name非空则true)
    You hava a name!
    dart生产模式下运行:(name != true,所以name转换成false了)
    ​
    dart检查模式下运行:
    抛出异常,name不是一个bool
  4. List列表

    • var list = [1,2,3];

    • 0 ... list.length-1

    • var constList = const [1,2,3,4] 这是一个不变得List对象

  5. Maps

    • var gifs = {

      'first':'parsing',

      'fifth':'trute',

      2:'data'

      };

  6. 两个空格作为缩进

  7. Runes \u 后面接4个16进制的数,多于4个需要加上{},Runes代表的是UTF-32编码,而Dart是UTF-16编码,字符串操作需小心

    Runes input = new Runes(
          '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
    
  8. Symbol类对象,在代码混淆的情况下也可以使用

  9. 和JS一样,方法也可以是对象,赋值给变量

  10. 方法可选参数

    enableFlags({bool bold,bool hidden}){...} enableFlags(bold: true, hidden: false);//默认参数 ​ enableFlags(bool bold,[bool hidden]) enableFlags(true) ​ void enableFlags({bool bold = false, bool hidden = false}){...}

  11. 级联操作 .. 可在一个对象上执行多个操作

  12. 捕获异常使用 try on 语句

    try{}on OutOfLlamasException{} try{} on OutOfLlamasException{}on Exception catch(e){}catch(e,s){ rethrow;}

  13. 常量构造函数,创建编译时常量 const A();

  14. get/set 方法是自动生成的(隐含的) final 没有set方法

  15. 命名构造函数

    class Point { num x; num y; ​ Point(this.x, this.y); ​ // Named constructor Point.fromJson(Map json) { x = json['x']; y = json['y']; } }

  16. 构造函数设置值

    class Point { num x; num y; ​ Point(this.x, this.y); ​ // Initializer list sets instance variables before // the constructor body runs. Point.fromJson(Map jsonMap) : x = jsonMap['x'], y = jsonMap['y'] { print('In Point.fromJson(): (x,x, y)'); } }

  17. 构造函数设定final变量的值

    class Point { final num x; final num y; final num distanceFromOrigin; ​ Point(x, y) : x = x, y = y, distanceFromOrigin = sqrt(x * x + y * y); }

  18. 重定向构造函数

    class Point { num x; num y; ​ // The main constructor for this class. Point(this.x, this.y); ​ // Delegates to the main constructor. Point.alongXAxis(num x) : this(x, 0); }

  19. 常量构造函数

    class ImmutablePoint { final num x; final num y; const ImmutablePoint(this.x, this.y); static final ImmutablePoint origin = const ImmutablePoint(0, 0); }

  20. 像 (++) 这种操作符不管是否定义 getter 都会正确的执行。 为了避免其他副作用, 操作符只调用 getter 一次,然后 把其值保存到一个临时变量中。

  21. 操作符可覆写

    class Vector { final int x; final int y; const Vector(this.x, this.y); ​ /// Overrides + (a + b). Vector operator +(Vector v) { return new Vector(x + v.x, y + v.y); } ​ /// Overrides - (a - b). Vector operator -(Vector v) { return new Vector(x - v.x, y - v.y); } }

  22. MAP LIST使用集合字面量

    var names = ['Seth', 'Kathy', 'Lars']; var pages = <String, String>{ 'index.html': 'Homepage', 'robots.txt': 'Hints for web robots', 'humans.txt': 'We are people, not machines' };

  23. 延迟载入库

    import 'package:deferred/hello.dart' deferred as hello; //使用 await 关键字暂停代码执行一直到库加载完成 greet() async { await hello.loadLibrary(); hello.printGreeting(); }

  24. async 方法自动返回Future

    Future lookUpVersion() async => '1.0.0';

  25. 类可以当作方法使用

    class WannabeFunction { call(String a, String b, String c) => 'aa b c!'; } ​ main() { var wf = new WannabeFunction(); var out = wf("Hi","there,","gang"); print('out'); }

  26. 所有的 Dart 代码在

<div>isolates</div>
中运行而不是线程。 每个 isolate 都有自己的堆内存,并且确保每个 isolate 的状态都不能被其他 isolate 访问。

27. 使用显示的名字保留类型信息

    typedef int Compare(Object a, Object b);
    ​
    class SortedCollection {
      Compare compare;
    ​
      SortedCollection(this.compare);
    }
    ​
     // Initial, broken implementation.
     int sort(Object a, Object b) => 0;
    ​
    main() {
      SortedCollection coll = new SortedCollection(sort);
      assert(coll.compare is Function);
      assert(coll.compare is Compare);
    }

28. 元注解

    import 'todo.dart';
    ​
    @todo('seth', 'make this do something')
    void doSomething() {
      print('do something');
    }

链表的K逆序

题目

有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点,例如1->2->3->4->5->6->7->8->null ,K = 3这个例子,调整后为 3->2->1->6->5->4->7->8->null,因为K == 3,所以每三个节点之间逆序,但其中得7,8不调整,因为只有两个节点不够一组。给定一个单链表的头指针,同时给定K值,返回逆序后的链表头指针

import java.util.Stack;

/**
 * 有一个单链表,请设计一个算法,使得每K个节点之间逆序, 如果最后不够K个节点一组,则不调整最后几个节点,
 * 例如1->2->3->4->5->6->7->8->null ,K = 3这个例子, 调整后为
 * 3->2->1->6->5->4->7->8->null,因为K == 3,所以每三个节点之间逆序,但其中得7,8不调整,
 * 因为只有两个节点不够一组。给定一个单链表的头指针,同时给定K值,返回逆序后的链表头指针。
 *
 */
public class DemoFive {
	public int[] reverseNode(int[] data, int K) {
		if (data == null || data.length < 2) {
			return data;
		}
		// 给定一个单链表的头指针
		Node head = createHead(data);
		// K 每K个之间反转 可以使用栈 空间复杂度O(N)
		int i = 1;
		Node previous = null;
		Node currentNode = head;
		Node beforeHead = head;

		Node lastTail = null;
		int count = 0;
		while (currentNode != null) {

			if (i == K) {
				// 逆转
				if (count == 0) {
					head = currentNode;
				} else {
					lastTail.next = currentNode;// 之前窗口链表的顶部和当前链表的尾部
				}
				int j = 0;

				previous = null;
				Node temp = currentNode.next;
				while (j < K) {
					if (j == 0) {
						lastTail = beforeHead;
					}
					Node node = beforeHead.next;
					beforeHead.next = previous;
					previous = beforeHead;
					beforeHead = node;
					j++;
					System.out.println("j == " + j);
					System.out.println(beforeHead == null);

				}
				// beforeHead = temp;
				currentNode = temp;// 这里需要赋值,因为最后一个节点,即第K个节点指向的是前一个节点了
				i = 1;
				count++;
			}

			// 这里currentNode可能会为空的,在执行完while语句后 temp 为空
			if (currentNode != null) {
				currentNode = currentNode.next;
			}
			i++;

		}
		currentNode = head;
		int m = 0;
		while (currentNode != null) {
			data[m] = currentNode.value;
			currentNode = currentNode.next;
			m++;
		}
		return data;
	}

	private Node createHead(int[] data) {
		Node head = new Node(data[0]);
		Node currentNode = head;
		for (int i = 1; i < data.length; i++) {
			Node newNode = new Node(data[i]);
			currentNode.next = newNode;
			currentNode = currentNode.next;
		}
		return head;
	}

	/**
	 * 和上述类似,代码可以优化,主要是利用栈的性质 方法二
	 * @param data
	 * @param K
	 * @return
	 */
	public int[] reverseByStack(int[] data, int K) {
		if (data == null || data.length < 2) {
			return data;
		}
		Stack<Node> temp = new Stack<>();
		int i = 1;
		Node head = createHead(data);
		Node currentNode = head;
		int count = 0;
		Node tail = null;
		Node firstNode = null;
		while (currentNode != null) {

			if (i == 1) {
				firstNode = currentNode;
			}
			temp.push(currentNode);

			if (temp.size() == K) {
				Node copy = currentNode.next;// 需要注意currentNode节点
				if (count == 0) {
					head = temp.peek();
				} else {
					tail.next = temp.peek();
				}
				while (temp.size() > 0) {

					Node node = temp.pop();
					if (temp.size() != 0) {
						node.next = temp.peek();

					} else {
						node.next = null;
						tail = node;

						System.out.println("===");
					}

				}
				//这块需要注意
				i = 1;
				currentNode = copy;
				firstNode = currentNode;
				temp.push(currentNode);
				count++;
			} else {
				if (tail != null) {
					tail.next = firstNode;
				}
			}

			if (currentNode != null) {
				currentNode = currentNode.next;
			}
			i++;
		}
		currentNode = head;
		int m = 0;
		while (currentNode != null) {
			data[m] = currentNode.value;
			currentNode = currentNode.next;
			m++;
		}
		return data;
	}
}

笔记三