This is the 14th day of my participation in Gwen Challenge


A conversation is a conversation

Recently, in several technical exchange groups, we often see discussion on the development of internal volume industry, what is internal volume? In short, people are working harder and more tired, but their happiness and gains have not increased, and in fact have decreased.

Take xi ‘an, a big city

Desperate to get their children into a better primary school, parents buy school districts, but good schools have a limited number of places for a year, no matter how expensive, and can’t increase the number of places. Such as a school for a year 250 primary school students, even around the school district room price to 3 one thousand square meters, or collect 250 students a year, but the parents in order to let the child the entrance, have to accept the unit price of 3, one thousand square meters, to buy a broken small old living, probably sold the original big house, because is restricted, the scene can only have a room.

What’s more, the school district housing policy will change, maybe every year, so you may not be able to go to school even if you buy a school district housing. For example, if there are 400 school-age children in the neighborhood, but there are still only 250 places, that means 150 people must not be able to get in. So what to do? The school made a ranking. Those with local household registration and consistent household registration have priority in admission, those with local household registration and inconsistent household registration rank second, and those without local household registration but with house ownership certificate rank third… What if none of that sticks? Very simple, multi-school drawing, the final can go to which school, computer random draw.

But in fact, the university is the same as the volume game, volume gives a person a sense of panic, we are driven by fear, do our best to compete for resources, but resources are limited, the more we fight for, the greater the damage of resources, and even disorderly competition will bring destructive outcome. But you don’t argue, get cheap by others, be scolded SB.

Society has developed to today, with the current productivity, enough to allow everyone to live a comfortable life. However, due to the distribution problem and the squeezing nature of capital, most people do not get the corresponding happiness from the development of productivity and science and technology. As a result, capital can get cheaper Labour and appreciate faster. But Labour itself has suffered more. Especially in this era when science and technology and knowledge are the primary productive forces, introversion is not conducive to social progress. Because knowledge production needs a relatively relaxed social environment. The better social welfare, the better knowledge production. The insecurity that comes with that kind of cutthroat competition is actually detrimental to technological progress. The knowledge producer in the inner volume state is very anxious. Accordingly, knowledge learners are also extremely anxious, and this kind of learning effect is not good. What’s more, such excessive competition greatly reduces people’s sense of security and happiness. … I imagine an ideal world in which everyone can do what they like to do and show the greatest enthusiasm for work on the premise of having enough food and clothing, so as to promote social progress. Of course, this is just the ideal.

I don’t know how to change the fate of the volume, but it can be, as far as possible early to prepare ahead of the volume, although it is a very tough year for 2020, but relative to the future, but is probably the easiest for a year, because in the future, along with the development of the volume will be more and more difficult, don’t again then regret missed opportunities in 2020. One of the best times to plant a tree was ten years ago, the other is now. Opportunities are always left to prepared people, you do not go to learn not to progress, when the time comes to be responsible for the next dish.

The body of the

Recently, one of my team members suddenly called to me: “Come and see, there is a strange thing, I can’t explain… Here’s the code:

 private static class Person {
        private int age;
        private String name;

        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString(a) {
            return name + ":"+ age; }}@Test
    public void test_collections2_filter(a) {
        Person lxy = new Person(35."lxy");
        Person xhf = new Person(34."xhf");
        Person nws = new Person(31."nws");
        List<Person> names = Lists.newArrayList(lxy, xhf, nws);

        Collection<Person> personAgeOver30 = Collections2.filter(names, p -> p.age > 30);
        System.out.println(personAgeOver30);//[lxy:35, xhf:34, nws:31]

        nws.setAge(25);
        System.out.println(personAgeOver30);//[lxy:35, xhf:34]
    }
Copy the code

It’s a little strange, how could an element in personAgeGt30 be missing? Guided by the idea that any program that behaves strangely has a reason behind it, I opened the source code for the Guava Collections2 class. Returned Collection is a live view of {@code unfiltered}; changes to one affect the other.

/**
   * Returns the elements of {@code unfiltered} that satisfy a predicate. The returned collection is
   * a live view of {@code unfiltered}; changes to one affect the other.
   *
   * <p>The resulting collection's iterator does not support {@code remove()}, but all other
   * collection methods are supported. When given an element that doesn't satisfy the predicate, the
   * collection's {@code add()} and {@code addAll()} methods throw an {@link
   * IllegalArgumentException}. When methods such as {@code removeAll()} and {@code clear()} are
   * called on the filtered collection, only elements that satisfy the filter will be removed from
   * the underlying collection.
   *
   * <p>The returned collection isn't threadsafe or serializable, even if {@code unfiltered} is.
   *
   * <p>Many of the filtered collection's methods, such as {@code size()}, iterate across every
   * element in the underlying collection and determine which elements satisfy the filter. When a
   * live view is <i>not</i> needed, it may be faster to copy {@code Iterables.filter(unfiltered,
   * predicate)} and use the copy.
   *
   * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>, as documented at
   * {@link Predicate#apply}. Do not provide a predicate such as {@code
   * Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals. (See {@link
   * Iterables#filter(Iterable, Class)} for related functionality.)
   *
   * <p><b>{@code Stream} equivalent:</b> {@link java.util.stream.Stream#filter Stream.filter}.
   */

Copy the code

The collections2. filter method returns only a view of the original list. So: Changing the filtered list affects the filtered list and vice versa. And we can also get the following points from the passage:

  1. Iterators for filtered lists do not support remove()

  2. Add elements that do not match the filter criteria, throwing IllegalArgumentException

  3. When the elements in the filtered list no longer meet the filtering conditions, it will affect the list that has been filtered out of the programmer’s instinct to decide to look at the source code. The core source code is as follows:

1.The add method:public boolean add(E element) {
       // IllegalArgumentException is thrown because the filter condition is not met
       checkArgument(predicate.apply(element));
       returnunfiltered.add(element); } delete by iterator is not supported for the following reasons:public abstract class UnmodifiableIterator<E> implements Iterator<E> {
   /** Constructor for use by subclasses. */
   protected UnmodifiableIterator(a) {}
   /**

* Guaranteed to throw an exception and leave the underlying data unmodified.
  *
* @throws UnsupportedOperationException always
* @deprecated Unsupported operation.
  */
  @Deprecated
  @Override
  public final void remove(a) {
  	throw newUnsupportedOperationException(); } The reasons for the change in print results:public String toString(a) {
      Iterator<E> it = iterator();
      if (! it.hasNext())
      	return "[]";
      StringBuilder sb = new StringBuilder();
      sb.append('[');
      for (;;) {
          E e = it.next();
          sb.append(e == this ? "(this Collection)" : e);
          if (! it.hasNext())
          return sb.append('] ').toString();
          sb.append(', ').append(' '); }}@Override
  public Iterator<E> iterator(a) {
  	return Iterators.filter(unfiltered.iterator(), predicate);
  }
Copy the code

The problem has been cleared up. How to fix it?

Option 1 (feasible) :

Instead of guava,

List<Person> names = Lists.newArrayList(lxy, xhf, nws);
    ArrayList<Person> persons = new ArrayList<>();
    for (Person p : names) {
    if(p.age > 30) { persons.add(p); }}Copy the code

Option 2 (feasible) :

Rewrap it in a container:

Collection<Person> personAgeGt30 = new ArrayList<(Collections2.filter(names, p -> p.age > 30));
Copy the code

Option 3 (if possible, use Java8 filters) :

List<Person> personAgeGt30 = names.stream().filter((Predicate<Person>) p -> p.age >30).collect(Collectors.toList());
Copy the code

Option 4 (Yes, use Guava’s coherent interface, IDEA editor will prompt you to use Java8 API instead)

ImmutableList<Person> personAgeGt30 = FluentIterable.from(names).filter(p -> p.age > 30).toList();
Copy the code

Recommended solution 3 supports Java8 in the production environment, but recommended solution 2 does not support Java8 in the production environment.

conclusion

In fact, there are many similar pits in the Java language, such as:

  • 1. Arrays.aslist () generates immutable lists.
  • 2. SubList generated child list, on the original list elements change, can lead to traverse the child list, add, delete throw ConcurrentModificationException,
  • 3. SubList’s modification of the subList will affect the data of the original list
  • 4. Modifying the Map keySet() method and the container generated by values() will affect the Map itself.

In general, read the source code before using any API, or at least read the comments.