TODO

堆外内存 cms算法

test的继承写法, Supplier, Callable, Future, 线程池,

https://github.com/iluwatar/java-design-patterns/blob/java9/singleton/src/test/java/com/iluwatar/singleton/SingletonTest.java

public abstract class SingletonTest<S> {

  /**
   * The singleton's getInstance method
   */
  private final Supplier<S> singletonInstanceMethod;

  /**
   * Create a new singleton test instance using the given 'getInstance' method
   *
   * @param singletonInstanceMethod The singleton's getInstance method
   */
  public SingletonTest(final Supplier<S> singletonInstanceMethod) {
    this.singletonInstanceMethod = singletonInstanceMethod;
  }

  /**
   * Test the singleton in a non-concurrent setting
   */
  @Test
  public void testMultipleCallsReturnTheSameObjectInSameThread() {
    // Create several instances in the same calling thread
    S instance1 = this.singletonInstanceMethod.get();
    S instance2 = this.singletonInstanceMethod.get();
    S instance3 = this.singletonInstanceMethod.get();
    // now check they are equal
    assertSame(instance1, instance2);
    assertSame(instance1, instance3);
    assertSame(instance2, instance3);
  }

  /**
   * Test singleton instance in a concurrent setting
   */
  @Test
  public void testMultipleCallsReturnTheSameObjectInDifferentThreads() throws Exception {
    assertTimeout(ofMillis(10000), () -> {
      // Create 10000 tasks and inside each callable instantiate the singleton class
      final List<Callable<S>> tasks = new ArrayList<>();
      for (int i = 0; i < 10000; i++) {
        tasks.add(this.singletonInstanceMethod::get);
      }

      // Use up to 8 concurrent threads to handle the tasks
      final ExecutorService executorService = Executors.newFixedThreadPool(8);
      final List<Future<S>> results = executorService.invokeAll(tasks);

      // wait for all of the threads to complete
      final S expectedInstance = this.singletonInstanceMethod.get();
      for (Future<S> res : results) {
        final S instance = res.get();
        assertNotNull(instance);
        assertSame(expectedInstance, instance);
      }

      // tidy up the executor
      executorService.shutdown();
    });

  }

}

Consumer Supplier 函数式接口

https://github.com/iluwatar/java-design-patterns/tree/master/factory-kit

计算机怎么实现除法

Division algorithm wiki

How is integer division implemented in Computer Hardware?

研究下这个问题 array[idx++]+=“a”

Why does array[idx++]+=“a” increase idx once in Java 8 but twice in Java 9 and 10?

语法 <T> type witness 和 泛型

https://stackoverflow.com/questions/31505015/java-generics-grammar

type witness

This question already has answers here:

Odd method call in java using a dot operator to access a generic list (5 answers)

Closed 4 years ago.

I couldn't understand the following statement while it is indeed compilable:

Say, the second , how can we put a single in front of the method name? I suspect it's a declaration of generics but cannot find it anywhere. But I only know the definition such as List, put `` behind a generics type. Can anybody point out me a tutorial for this grammar or find the duplicated question (sorry I didn't find one during my quick search)?

Many thanks!

Ans:

This is called a type witness, and it is referenced in the Type Inference trail:

The generic method addBox defines one type parameter named U. Generally, a Java compiler can infer the type parameters of a generic method call. Consequently, in most cases, you do not have to specify them. For example, to invoke the generic method addBox, you can specify the type parameter with a type witness as follows:

Effectively, a type witness lets the developer step in to resolve cases in which the type engine can't properly infer what type a value will result in. You'd see its usage more commonly and prevalently in Java 7, whereas Java 8 has improved its type inference capabilities.

泛型

返回值写的<T> List<T>

https://www.cnblogs.com/dengchengchao/p/9717097.html

擦除的地点---边界

这是在《Effective Java》中看到的例子,编译此代码没有问题,但是运行的时候却会类型转换错误:Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

当时对泛型并没有一个很好的认识,一直不明白为什么会有Object[]转换到String[]的错误。现在我们来分析一下:

  • 首先看toArray方法,由本章最开始所说泛型使用擦除实现的原因是为了保持有泛型和没有泛型所产生的代码一致,那么:

生成的二进制文件是一致的。

进而剥开可变数组的语法糖:

是一致的。 那么调用pickTwo方法实际编译器会帮我进行类型转换

可以看到,问题就在于可变参数那里,使用可变参数编译器会自动把我们的参数包装为一个数组传递给对应的方法,而这个数组的包装在泛型中,会最终翻译为new Object,那么toArray接受的实际类型是一个Object[],当然不能强制转换为String[]

上面代码出错的关键点就在于泛型经过擦除后,类型变为了Object导致可变参数直接包装出了一个Object数组产生的类型转换失败。

String stream codepoints chars 编码问题

https://stackoverflow.com/questions/31977356/using-streams-to-manipulate-a-string

Supplementary characters

Supplementary characters are characters with code points in the range U+10000 to U+10FFFF, that is, those characters that could not be represented in the original 16-bit design of Unicode. The set of characters from U+0000 to U+FFFF is sometimes referred to as the Basic Multilingual Plane (BMP). Thus, each Unicode character is either in the BMP or a supplementary character.

https://www.oracle.com/technical-resources/articles/javase/supplementary.html#:~:text=Supplementary%20characters%20are%20characters%20with,Basic%20Multilingual%20Plane%20(BMP).

char 2个字符

when converting between byte[] and char[]/String or between InputStream and Reader or between OutputStream and Writer, you should always specify which encoding you want to use. If you don't, then your code will be platform-dependent.

char本身是2个byte,但是可能是2个char来表示一个字。byte和String转换时默认使用本地的编码方式,所以有可能会乱码。

https://stackoverflow.com/questions/5078314/isnt-the-size-of-character-in-java-2-bytes

A char represents a character in Java (*). It is 2 bytes large (at least that's what the valid value range suggests).

That doesn't necessarily mean that every representation of a character is 2 bytes long. In fact many encodings only reserve 1 byte for every character (or use 1 byte for the most common characters).

When you call the String(byte[]) constructor you ask Java to convert the byte[] to a String using the platform default encoding. Since the platform default encoding is usually a 1-byte encoding such as ISO-8859-1 or a variable-length encoding such as UTF-8, it can easily convert that 1 byte to a single character.

If you run that code on a platform that uses UTF-16 (or UTF-32 or UCS-2 or UCS-4 or ...) as the platform default encoding, then you will not get a valid result (you'll get a String containing the Unicode Replacement Character instead).

That's one of the reasons why you should not depend on the platform default encoding: when converting between byte[] and char[]/String or between InputStream and Reader or between OutputStream and Writer, you should always specify which encoding you want to use. If you don't, then your code will be platform-dependent.

(*) that's not entirely true: a char represents a UTF-16 codepoint. Either one or two UTF-16 codepoints represent a Unicode codepoint. A Unicode codepoint usually represents a character, but sometimes multiple Unicode codepoints are used to make up a single character. But the approximation above is close enough to discuss the topic at hand.

Last updated

Was this helpful?