Guava: Working with Collections I

本文介绍了Google Guava库中各种集合类的使用方法,包括FluentIterable、Lists、Sets、Maps等高级API,并通过示例展示了如何进行过滤、转换、分区等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Classes with useful static methods for working with lists, maps and sets

2. The Range class used to represent the boundaries around a continuous set of values

3. Immutable Collections

4. Bimaps

5. The Table collection type, which is a very powerful collection that is a replacement for using a map of maps.

6. Multimaps, which allow us to have more than one value associated with unique key.

7. The FluentIterable class, which represents a set of powerful interfaces for working with Iterable instances.

8. The Ordering class that gives us enhanced abilities when working with Comparators

 

1. FluentIterable

    The FluentIterable class represents a powerful interface for working with Iterable instances in fluent style of programming.

    The fluent programming style allows us to chain method calls together, making for a more readable code.

    1> FluentIterable.filter(Predicate<T>)

    @Test
    public void filterTest() {
	List<String> list = Lists.newArrayList("A", "B", "C", "D");

	List<String> filteredList = FluentIterable.from(list)
		.filter(Predicates.and(new Predicate<String>() {
		    public boolean apply(String input) {
			return "A".compareTo(input) < 0;
		    }
		}, new Predicate<String>() {
		    public boolean apply(String input) {
			return "D".compareTo(input) > 0;
		    }
		})).toList();

	assertEquals(2, filteredList.size());
	assertEquals("B", filteredList.get(0));
	assertEquals("C", filteredList.get(1));
    }

         source code:

  public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
    return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable
        : new FluentIterable<E>(iterable) {
          @Override
          public Iterator<E> iterator() {
            return iterable.iterator();
          }
        };
  }

  FluentIterable(Iterable<E> iterable) {
    this.iterable = checkNotNull(iterable); // set passed in iterable as property
  }

  public final FluentIterable<E> filter(Predicate<? super E> predicate) {
    return from(Iterables.filter(iterable, predicate));
  }

  public static <T> UnmodifiableIterator<T> filter(
      final Iterator<T> unfiltered, final Predicate<? super T> predicate) {
    return new AbstractIterator<T>() {
      @Override protected T computeNext() {
        while (unfiltered.hasNext()) {
          T element = unfiltered.next();
          if (predicate.apply(element)) {
            return element;
          }
        }
        return endOfData();
      }
    };
  }

    2> FluentIterable.transform(Function<F, T>)

    @Test
    public void transformTest() {
	List<String> list = Lists.newArrayList("A", "B", "C", "D", "E");

	Map<String, String> map = Maps.newHashMap();
	map.put("A", "A for Alcohol");
	map.put("B", "B for Boycott");
	map.put("C", "C for Combine");
	List<String> transformedList = FluentIterable.from(list)
		.transform(Functions.forMap(map, "Not Defined")).toList();

	List<String> expectedList = Lists.newArrayList("A for Alcohol",
		"B for Boycott", "C for Combine", "Not Defined", "Not Defined");

	assertEquals(expectedList, transformedList);
    }

        source code:

  public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
    return from(Iterables.transform(iterable, function));
  }

  public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable,
      final Function<? super F, ? extends T> function) {
    return new FluentIterable<T>() {
      @Override
      public Iterator<T> iterator() {
        return Iterators.transform(fromIterable.iterator(), function);
      }
    };
  }

  public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator,
      final Function<? super F, ? extends T> function) {
    return new TransformedIterator<F, T>(fromIterator) {
      @Override
      T transform(F from) {
        return function.apply(from);
      }
    };
  }

 

2. Lists

    1> Lists.newXXXList(): Factory method to simplify the creation of Generic Collection

  public static <E> ArrayList<E> newArrayList(E... elements) {
    int capacity = computeArrayListCapacity(elements.length);
    ArrayList<E> list = new ArrayList<E>(capacity);
    Collections.addAll(list, elements);
    return list;
  }

   2> Lists.partition()

    @Test
    public void partitionTest() {
	List<String> strList = Lists.newArrayList("A", "B", "C", "D");

	List<List<String>> partedStrList = Lists.partition(strList, 2);
	assertEquals(2, partedStrList.size());
	assertEquals(2, partedStrList.get(0).size());
	assertEquals(2, partedStrList.get(1).size());

	partedStrList = Lists.partition(strList, 3);
	assertEquals(2, partedStrList.size());
	assertEquals(3, partedStrList.get(0).size());
	assertEquals(1, partedStrList.get(1).size());
    }

        source code:

  public static <T> List<List<T>> partition(List<T> list, int size) {
    return (list instanceof RandomAccess)
        ? new RandomAccessPartition<T>(list, size)
        : new Partition<T>(list, size);
  }

  private static class Partition<T> extends AbstractList<List<T>> {
    final List<T> list;
    final int size;

    Partition(List<T> list, int size) {
      this.list = list;
      this.size = size;
    }

    @Override public List<T> get(int index) {
      int start = index * size;
      int end = Math.min(start + size, list.size());
      return list.subList(start, end);
    }

    @Override public int size() {
      return IntMath.divide(list.size(), size, RoundingMode.CEILING);
    }

    @Override public boolean isEmpty() {
      return list.isEmpty();
    }
  }

 

3. Sets

    1> Sets.newXXXSet(): Factory method to simplify the creation of Generic Collection

  public static <E> HashSet<E> newHashSet(E... elements) {
    HashSet<E> set = newHashSetWithExpectedSize(elements.length);
    Collections.addAll(set, elements);
    return set;
  }

    2> Sets.difference and Sets.intersection and Sets.union

    @Test
    public void partitionTest() {
	Set<String> strSet1 = Sets.newHashSet("A", "B", "C", "D");
	Set<String> strSet2 = Sets.newHashSet("D", "M", "O", "G");
	Set<String> diffSet = Sets.difference(strSet1, strSet2);
	assertEquals(3, diffSet.size());

	Set<String> interSet = Sets.intersection(strSet1, strSet2);
	assertEquals(1, interSet.size());

	Set<String> unionSet = Sets.union(strSet1, strSet2);
	assertEquals(7, unionSet.size());
    }

        source code:

  public static <E> SetView<E> difference(
      final Set<E> set1, final Set<?> set2) {

    final Predicate<Object> notInSet2 = Predicates.not(Predicates.in(set2));
    return new SetView<E>() {
      @Override public Iterator<E> iterator() {
        return Iterators.filter(set1.iterator(), notInSet2);
      }
      @Override public int size() {
        return Iterators.size(iterator());
      }
      @Override public boolean isEmpty() {
        return set2.containsAll(set1);
      }
      @Override public boolean contains(Object element) {
        return set1.contains(element) && !set2.contains(element);
      }
    };
  }
  public static <E> SetView<E> intersection(
      final Set<E> set1, final Set<?> set2) {

    final Predicate<Object> inSet2 = Predicates.in(set2);
    return new SetView<E>() {
      @Override public Iterator<E> iterator() {
        return Iterators.filter(set1.iterator(), inSet2);
      }
      @Override public int size() {
        return Iterators.size(iterator());
      }
      @Override public boolean isEmpty() {
        return !iterator().hasNext();
      }
      @Override public boolean contains(Object object) {
        return set1.contains(object) && set2.contains(object);
      }
      @Override public boolean containsAll(Collection<?> collection) {
        return set1.containsAll(collection)
            && set2.containsAll(collection);
      }
    };
  }
  public static <E> SetView<E> union(
      final Set<? extends E> set1, final Set<? extends E> set2) {

    final Set<? extends E> set2minus1 = difference(set2, set1);

    return new SetView<E>() {
      @Override public int size() {
        return set1.size() + set2minus1.size();
      }
      @Override public boolean isEmpty() {
        return set1.isEmpty() && set2.isEmpty();
      }
      @Override public Iterator<E> iterator() {
        return Iterators.unmodifiableIterator(
            Iterators.concat(set1.iterator(), set2minus1.iterator()));
      }
      @Override public boolean contains(Object object) {
        return set1.contains(object) || set2.contains(object);
      }
      @Override public <S extends Set<E>> S copyInto(S set) {
        set.addAll(set1);
        set.addAll(set2);
        return set;
      }
      @Override public ImmutableSet<E> immutableCopy() {
        return new ImmutableSet.Builder<E>()
            .addAll(set1).addAll(set2).build();
      }
    };
  }

 

4. Maps

    1> Maps.newXXXMap()

    2> Maps.uniqueIndex(Iterator<V>, Function<V, K>)

    @Test
    public void traditionalTest() {
	List<Person> personList = Lists.newArrayList(new Person("Davy", "Male",
		24), new Person("Calypso", "Female", 22));
	Map<String, Person> map = Maps.newHashMap();
	for (Person p : personList) {
	    map.put(p.getName(), p);
	}

	assertEquals(2, map.size());
    }

    @Test
    public void uniqueIndexTest() {
	List<Person> personList = Lists.newArrayList(new Person("Davy", "Male",
		24), new Person("Calypso", "Female", 22));
	Map<String, Person> map = Maps.uniqueIndex(personList,
		new Function<Person, String>() {
		    public String apply(Person input) {
			return input.getName();
		    }
		});

	assertEquals(2, map.size());
    }

    class Person {
	String name;
	String gender;
	int age;

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

	public String getName() {
	    return name;
	}

	public String getGender() {
	    return gender;
	}

	public int getAge() {
	    return age;
	}

	@Override
	public String toString() {
	    return "Person [name=" + name + ", gender=" + gender + ", age="
		    + age + "]";
	}
    }

        source code:

  public static <K, V> ImmutableMap<K, V> uniqueIndex(
      Iterable<V> values, Function<? super V, K> keyFunction) {
    return uniqueIndex(values.iterator(), keyFunction);
  }

  public static <K, V> ImmutableMap<K, V> uniqueIndex(
      Iterator<V> values, Function<? super V, K> keyFunction) {
    ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
    while (values.hasNext()) {
      V value = values.next();
      builder.put(keyFunction.apply(value), value);
    }
    return builder.build();
  }

    3> Maps.asMap(Set<K>, Function<K, V>)

    The Maps.asMap method takes a set of objects to be used as keys, and Function is applied to each key to generate the value for entry into a map instance.

    @Test
    public void asMapTest() {
	Set<String> nameSet = Sets.newHashSet("Davy", "Calypso");
	Map<String, Person> map = Maps.asMap(nameSet,
		new Function<String, Person>() {
		    public Person apply(String name) {
			return new Person(name, "UNKNOWN", 0);
		    }
		});
	assertEquals(2, map.size());
    }

    4> Maps.transformEntries

    @Test
    public void transformEntriesTest() {
	Map<String, Person> personMap = Maps.newHashMap();
	personMap.put("Davy", new Person("Davy", "Male", 24));
	personMap.put("Calypso", new Person("Calypso", "Female", 22));
	Map<String, People> peopleMap = Maps.transformEntries(personMap,
		new EntryTransformer<String, Person, People>() {
		    public People transformEntry(String key, Person value) {
			return new People(value.getName(), value.getGender());
		    }
		});
	assertEquals(2, peopleMap.size());
    }

 

5. Multimaps

    1> ArrayListMultimap = HashMap<K, ArrayList<V>>

    2> HashMultimap = HashMap<K, HashSet<V>>

    3> LinkedHashMultimap = LinkedHashMap<K, LinkedHashSet<V>>

    4> TreeMultimap = TreeMap<K, TreeSet<V>>

    5> LinkedListMultimap = HashMap<K, LinkedList<V>>

         Q: Why the realization of LinkedListMultimap is different from others' ?

              Why don't they simply extends AbstractListMultimap and then generalize method createCollection() ?

 

6. Exercises:

    1> Filter Lists

    @Test
    public void filterListTest() {
	List<String> list = Lists.newArrayList("A", "B", "C", "D");
	List<String> filteredList = FluentIterable.from(list)
		.filter(new Predicate<String>() {
		    @Override
		    public boolean apply(String input) {
			return "A".compareTo(input) < 0;
		    }
		}).toList();
	List<String> expectedList = Lists.newArrayList("B", "C", "D");
	assertEquals(expectedList, filteredList);

	List<Object> objList = Lists.<Object> newArrayList("A", "B",
		new Double(1.2), new Double(1.0));
	List<Double> doubleList = FluentIterable.from(objList)
		.filter(Double.class).toList();
	List<Double> expDoubleList = Lists.newArrayList(new Double(1.2),
		new Double(1.0));
	assertEquals(expDoubleList, doubleList);
    }

    2> Transform Lists

    @Test
    public void transformListTest() {
	List<String> list = Lists.newArrayList("A", "B", "C", "D");
	List<String> transformedList = FluentIterable.from(list)
		.transform(new Function<String, String>() {
		    @Override
		    public String apply(String input) {
			return input.concat("-Postfix");
		    }
		}).toList();
	List<String> expectedList = Lists.newArrayList("A-Postfix",
		"B-Postfix", "C-Postfix", "D-Postfix");
	assertEquals(expectedList, transformedList);

	transformedList = FluentIterable.from(list)
		.filter(new Predicate<String>() {
		    @Override
		    public boolean apply(String input) {
			return !"A".equals(input);
		    }
		}).transformAndConcat(new Function<String, Iterable<String>>() {
		    @Override
		    public Iterable<String> apply(String input) {
			return Lists.newArrayList(input,
				input.concat("-Postfix"));
		    }
		}).toList();
	expectedList = Lists.newArrayList("B", "B-Postfix", "C", "C-Postfix",
		"D", "D-Postfix");
	assertEquals(expectedList, transformedList);
    }

    3> Filter Map

    @Test
    public void filterMapTest() {
	Map<String, String> map = Maps.newHashMap();
	map.put("A", "A for Alcohol");
	map.put("B", "B for Boycott");
	map.put("C", "C for Cowboy");
	map.put("D", "D for Dodge");

	Map<String, String> filteredMap = Maps.filterEntries(map,
		new Predicate<Map.Entry<String, String>>() {
		    @Override
		    public boolean apply(Entry<String, String> input) {
			return "A".equals(input.getKey())
				&& "A for Alcohol".equals(input.getValue());
		    }
		});
	Map<String, String> expectedMap = Maps.newHashMap();
	expectedMap.put("A", "A for Alcohol");
	assertEquals(expectedMap, filteredMap);

	filteredMap = Maps.filterKeys(map, new Predicate<String>() {
	    @Override
	    public boolean apply(String input) {
		return input.equals("B");
	    }
	});
	expectedMap = Maps.newHashMap();
	expectedMap.put("B", "B for Boycott");
	assertEquals(expectedMap, filteredMap);

	filteredMap = Maps.filterValues(map, new Predicate<String>() {
	    @Override
	    public boolean apply(String input) {
		return input.equals("C for Cowboy");
	    }
	});
	expectedMap = Maps.newHashMap();
	expectedMap.put("C", "C for Cowboy");
	assertEquals(expectedMap, filteredMap);
    }

    4> Transform Map

    @Test
    public void transformMapTest() {
	Map<String, String> map = Maps.newHashMap();
	map.put("A", "A for Alcohol");
	map.put("B", "B for Boycott");
	map.put("C", "C for Cowboy");
	map.put("D", "D for Dodge");

	Map<String, Person> transformedMap = Maps.transformValues(map,
		new Function<String, Person>() {
		    @Override
		    public Person apply(String input) {
			return new Person(input);
		    }
		});
	Map<String, Person> expectedMap = Maps.newHashMap();
	expectedMap.put("A", new Person("A for Alcohol"));
	expectedMap.put("B", new Person("B for Boycott"));
	expectedMap.put("C", new Person("C for Cowboy"));
	expectedMap.put("D", new Person("D for Dodge"));
	assertEquals(expectedMap, transformedMap);

	transformedMap = Maps.transformEntries(map,
		new EntryTransformer<String, String, Person>() {
		    @Override
		    public Person transformEntry(String key, String value) {
			return "A".equals(key) ? new Person(key) : new Person(
				value);
		    }
		});
	expectedMap = Maps.newHashMap();
	expectedMap.put("A", new Person("A"));
	expectedMap.put("B", new Person("B for Boycott"));
	expectedMap.put("C", new Person("C for Cowboy"));
	expectedMap.put("D", new Person("D for Dodge"));
	assertEquals(expectedMap, transformedMap);
    }

    5> Add element into ImmutableList/ImmutableSet/ImmutableMap

    @Test
    public void test() {
	List<String> list = Lists.newArrayList("A", "B", "C", "D", "E");

	List<String> filteredList = FluentIterable.from(list)
		.filter(new Predicate<String>() {
		    @Override
		    public boolean apply(String input) {
			return "A".equals(input) || "D".equals(input);
		    }
		}).toList();

	filteredList = ImmutableList.<String> builder().addAll(filteredList)
		.add("F").build();

	assertEquals(Lists.newArrayList("A", "D", "F"), filteredList);
    }
    @Test
    public void test2() {
	Function<String, String> postfixFunction = new Function<String, String>() {
	    @Override
	    public String apply(String input) {
		return input.concat("-Postfix");
	    }
	};
	Map<String, String> map = Maps.toMap(
		Lists.newArrayList("A", "B", "C", "D"), postfixFunction);

	Map<String, String> buildedMap = ImmutableMap
		.<String, String> builder().putAll(map).put("E", "E-Postfix")
		.build();

	assertEquals(Maps.toMap(Lists.newArrayList("A", "B", "C", "D", "E"),
		postfixFunction), buildedMap);
    }

    Q: Why don't they return MutableCollection/MutableMap instead of ImmutableCollction/ImmutableMap for handy future manipulation(add/remove)?

 

Reference Links:
1) Getting Started with Google Guava -Bill Bejeck

2) http://stackoverflow.com/questions/12937938/adding-and-removing-items-to-a-guava-immutablelist

F:\zhang\jdk18\bin\java.exe "-javaagent:F:\zhang\IDEA\IntelliJ IDEA 2023.3.4\lib\idea_rt.jar=57121:F:\zhang\IDEA\IntelliJ IDEA 2023.3.4\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath F:\zhang\IDEA\IDEAprojects\Covid-2304\target\classes;C:\Users\user\.m2\repository\org\apache\hadoop\hadoop-common\3.2.2\hadoop-common-3.2.2.jar;C:\Users\user\.m2\repository\org\apache\hadoop\hadoop-annotations\3.2.2\hadoop-annotations-3.2.2.jar;C:\Users\user\.m2\repository\com\google\guava\guava\27.0-jre\guava-27.0-jre.jar;C:\Users\user\.m2\repository\com\google\guava\failureaccess\1.0\failureaccess-1.0.jar;C:\Users\user\.m2\repository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:\Users\user\.m2\repository\org\checkerframework\checker-qual\2.5.2\checker-qual-2.5.2.jar;C:\Users\user\.m2\repository\com\google\errorprone\error_prone_annotations\2.2.0\error_prone_annotations-2.2.0.jar;C:\Users\user\.m2\repository\com\google\j2objc\j2objc-annotations\1.1\j2objc-annotations-1.1.jar;C:\Users\user\.m2\repository\org\codehaus\mojo\animal-sniffer-annotations\1.17\animal-sniffer-annotations-1.17.jar;C:\Users\user\.m2\repository\commons-cli\commons-cli\1.2\commons-cli-1.2.jar;C:\Users\user\.m2\repository\org\apache\commons\commons-math3\3.1.1\commons-math3-3.1.1.jar;C:\Users\user\.m2\repository\org\apache\httpcomponents\httpclient\4.5.13\httpclient-4.5.13.jar;C:\Users\user\.m2\repository\org\apache\httpcomponents\httpcore\4.4.13\httpcore-4.4.13.jar;C:\Users\user\.m2\repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;C:\Users\user\.m2\repository\commons-io\commons-io\2.5\commons-io-2.5.jar;C:\Users\user\.m2\repository\commons-net\commons-net\3.6\commons-net-3.6.jar;C:\Users\user\.m2\repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\Users\user\.m2\repository\javax\servlet\javax.servlet-api\3.1.0\javax.ser
03-19
D:\software\Java\jdk1.8.0_451\bin\java.exe -Dvisualgc.id=3129413093850500 -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.7\lib\idea_rt.jar=14415:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.7\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.7\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.7\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.7\plugins\junit\lib\junit-rt.jar;D:\software\Java\jdk1.8.0_451\jre\lib\charsets.jar;D:\software\Java\jdk1.8.0_451\jre\lib\deploy.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\access-bridge-64.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\cldrdata.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\dnsns.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\jaccess.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\localedata.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\nashorn.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\sunec.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\sunjce_provider.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\sunmscapi.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\sunpkcs11.jar;D:\software\Java\jdk1.8.0_451\jre\lib\ext\zipfs.jar;D:\software\Java\jdk1.8.0_451\jre\lib\javaws.jar;D:\software\Java\jdk1.8.0_451\jre\lib\jce.jar;D:\software\Java\jdk1.8.0_451\jre\lib\jfr.jar;D:\software\Java\jdk1.8.0_451\jre\lib\jsse.jar;D:\software\Java\jdk1.8.0_451\jre\lib\management-agent.jar;D:\software\Java\jdk1.8.0_451\jre\lib\plugin.jar;D:\software\Java\jdk1.8.0_451\jre\lib\resources.jar;D:\software\Java\jdk1.8.0_451\jre\lib\rt.jar;D:\workspace\git_localrepo\access-control\person\person-core\target\test-classes;D:\workspace\git_localrepo\access-control\person\person-core\target\classes;D:\workspace\git_localrepo\access-control\person\person-api\target\classes;D:\workspace\git_localrepo\access-control\person\person-port-repository-api\target\classes;F:\Program Files\repository\org\springframework\data\spring-data-mongodb\3.4.7\spring-data-mongodb-3.4.7.jar;F:\Program Files\repository\org\springframework\spring-tx\5.3.25\spring-tx-5.3.25.jar;F:\Program Files\repository\org\springframework\spring-context\5.3.25\spring-context-5.3.25.jar;F:\Program Files\repository\org\springframework\spring-aop\5.3.25\spring-aop-5.3.25.jar;F:\Program Files\repository\org\springframework\spring-beans\5.3.25\spring-beans-5.3.25.jar;F:\Program Files\repository\org\springframework\spring-expression\5.3.25\spring-expression-5.3.25.jar;F:\Program Files\repository\org\springframework\data\spring-data-commons\2.7.7\spring-data-commons-2.7.7.jar;F:\Program Files\repository\org\mongodb\mongodb-driver-core\4.6.1\mongodb-driver-core-4.6.1.jar;F:\Program Files\repository\org\mongodb\bson\4.6.1\bson-4.6.1.jar;F:\Program Files\repository\org\mongodb\bson-record-codec\4.6.1\bson-record-codec-4.6.1.jar;F:\Program Files\repository\com\tplink\cdd\vigi-common-mongo\2.0.105-SNAPSHOT\vigi-common-mongo-2.0.105-SNAPSHOT.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-data-mongodb\2.7.8\spring-boot-starter-data-mongodb-2.7.8.jar;F:\Program Files\repository\org\mongodb\mongodb-driver-sync\4.6.1\mongodb-driver-sync-4.6.1.jar;F:\Program Files\repository\com\tplink\cdd\vigi-common\2.0.105-SNAPSHOT\vigi-common-2.0.105-SNAPSHOT.jar;F:\Program Files\repository\com\google\guava\guava\29.0-jre\guava-29.0-jre.jar;F:\Program Files\repository\com\google\guava\failureaccess\1.0.1\failureaccess-1.0.1.jar;F:\Program Files\repository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;F:\Program Files\repository\org\checkerframework\checker-qual\2.11.1\checker-qual-2.11.1.jar;F:\Program Files\repository\com\google\errorprone\error_prone_annotations\2.3.4\error_prone_annotations-2.3.4.jar;F:\Program Files\repository\com\google\j2objc\j2objc-annotations\1.3\j2objc-annotations-1.3.jar;F:\Program Files\repository\org\json\json\20230227\json-20230227.jar;F:\Program Files\repository\com\fasterxml\jackson\core\jackson-databind\2.13.4.2\jackson-databind-2.13.4.2.jar;F:\Program Files\repository\cn\hutool\hutool-core\5.8.15\hutool-core-5.8.15.jar;F:\Program Files\repository\cn\hutool\hutool-crypto\5.8.15\hutool-crypto-5.8.15.jar;F:\Program Files\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;F:\Program Files\repository\org\hibernate\validator\hibernate-validator\6.2.5.Final\hibernate-validator-6.2.5.Final.jar;F:\Program Files\repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;F:\Program Files\repository\org\jboss\logging\jboss-logging\3.4.3.Final\jboss-logging-3.4.3.Final.jar;F:\Program Files\repository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;F:\Program Files\repository\org\springframework\boot\spring-boot\2.7.8\spring-boot-2.7.8.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-configuration-processor\2.7.8\spring-boot-configuration-processor-2.7.8.jar;F:\Program Files\repository\org\springframework\spring-web\5.3.25\spring-web-5.3.25.jar;F:\Program Files\repository\io\micrometer\micrometer-registry-prometheus\1.9.7\micrometer-registry-prometheus-1.9.7.jar;F:\Program Files\repository\io\prometheus\simpleclient_common\0.15.0\simpleclient_common-0.15.0.jar;F:\Program Files\repository\io\prometheus\simpleclient\0.15.0\simpleclient-0.15.0.jar;F:\Program Files\repository\io\prometheus\simpleclient_tracer_otel\0.15.0\simpleclient_tracer_otel-0.15.0.jar;F:\Program Files\repository\io\prometheus\simpleclient_tracer_common\0.15.0\simpleclient_tracer_common-0.15.0.jar;F:\Program Files\repository\io\prometheus\simpleclient_tracer_otel_agent\0.15.0\simpleclient_tracer_otel_agent-0.15.0.jar;F:\Program Files\repository\com\tplink\nbu\common\platform-cloud-sdk\2.1.60\platform-cloud-sdk-2.1.60.jar;F:\Program Files\repository\org\apache\httpcomponents\httpasyncclient\4.1.5\httpasyncclient-4.1.5.jar;F:\Program Files\repository\org\apache\httpcomponents\httpcore-nio\4.4.16\httpcore-nio-4.4.16.jar;F:\Program Files\repository\com\tplink\nbu\common\nbu-common-utils\2.1.60\nbu-common-utils-2.1.60.jar;F:\Program Files\repository\org\softee\pojo-mbean\1.1\pojo-mbean-1.1.jar;F:\Program Files\repository\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;F:\Program Files\repository\com\tplink\nbu\common\pii\2.1.60\pii-2.1.60.jar;F:\Program Files\repository\com\jayway\jsonpath\json-path\2.7.0\json-path-2.7.0.jar;F:\Program Files\repository\net\minidev\json-smart\2.4.8\json-smart-2.4.8.jar;F:\Program Files\repository\net\minidev\accessors-smart\2.4.8\accessors-smart-2.4.8.jar;F:\Program Files\repository\org\ow2\asm\asm\9.1\asm-9.1.jar;F:\Program Files\repository\javax\servlet\javax.servlet-api\4.0.1\javax.servlet-api-4.0.1.jar;F:\Program Files\repository\io\netty\netty-all\4.1.87.Final\netty-all-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-buffer\4.1.87.Final\netty-buffer-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec\4.1.87.Final\netty-codec-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-dns\4.1.87.Final\netty-codec-dns-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-haproxy\4.1.87.Final\netty-codec-haproxy-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-http\4.1.87.Final\netty-codec-http-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-http2\4.1.87.Final\netty-codec-http2-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-memcache\4.1.87.Final\netty-codec-memcache-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-mqtt\4.1.87.Final\netty-codec-mqtt-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-redis\4.1.87.Final\netty-codec-redis-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-smtp\4.1.87.Final\netty-codec-smtp-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-socks\4.1.87.Final\netty-codec-socks-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-stomp\4.1.87.Final\netty-codec-stomp-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-codec-xml\4.1.87.Final\netty-codec-xml-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-common\4.1.87.Final\netty-common-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-handler\4.1.87.Final\netty-handler-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-native-unix-common\4.1.87.Final\netty-transport-native-unix-common-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-handler-proxy\4.1.87.Final\netty-handler-proxy-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-handler-ssl-ocsp\4.1.87.Final\netty-handler-ssl-ocsp-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-resolver\4.1.87.Final\netty-resolver-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-resolver-dns\4.1.87.Final\netty-resolver-dns-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport\4.1.87.Final\netty-transport-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-rxtx\4.1.87.Final\netty-transport-rxtx-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-sctp\4.1.87.Final\netty-transport-sctp-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-udt\4.1.87.Final\netty-transport-udt-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-classes-epoll\4.1.87.Final\netty-transport-classes-epoll-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-classes-kqueue\4.1.87.Final\netty-transport-classes-kqueue-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-resolver-dns-classes-macos\4.1.87.Final\netty-resolver-dns-classes-macos-4.1.87.Final.jar;F:\Program Files\repository\io\netty\netty-transport-native-epoll\4.1.87.Final\netty-transport-native-epoll-4.1.87.Final-linux-x86_64.jar;F:\Program Files\repository\io\netty\netty-transport-native-epoll\4.1.87.Final\netty-transport-native-epoll-4.1.87.Final-linux-aarch_64.jar;F:\Program Files\repository\io\netty\netty-transport-native-kqueue\4.1.87.Final\netty-transport-native-kqueue-4.1.87.Final-osx-x86_64.jar;F:\Program Files\repository\io\netty\netty-transport-native-kqueue\4.1.87.Final\netty-transport-native-kqueue-4.1.87.Final-osx-aarch_64.jar;F:\Program Files\repository\io\netty\netty-resolver-dns-native-macos\4.1.87.Final\netty-resolver-dns-native-macos-4.1.87.Final-osx-x86_64.jar;F:\Program Files\repository\io\netty\netty-resolver-dns-native-macos\4.1.87.Final\netty-resolver-dns-native-macos-4.1.87.Final-osx-aarch_64.jar;F:\Program Files\repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;F:\Program Files\repository\net\sourceforge\javacsv\javacsv\2.0\javacsv-2.0.jar;F:\Program Files\repository\com\googlecode\java-ipv6\java-ipv6\0.17\java-ipv6-0.17.jar;F:\Program Files\repository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar;F:\Program Files\repository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar;F:\Program Files\repository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar;F:\Program Files\repository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;F:\Program Files\repository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar;F:\Program Files\repository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar;F:\Program Files\repository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar;F:\Program Files\repository\org\apache\commons\commons-compress\1.19\commons-compress-1.19.jar;F:\Program Files\repository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar;F:\Program Files\repository\org\bouncycastle\bcprov-jdk15on\1.68\bcprov-jdk15on-1.68.jar;F:\Program Files\repository\org\bouncycastle\bcpkix-jdk15on\1.68\bcpkix-jdk15on-1.68.jar;F:\Program Files\repository\org\mapstruct\mapstruct\1.4.2.Final\mapstruct-1.4.2.Final.jar;F:\Program Files\repository\org\mapstruct\mapstruct-processor\1.4.2.Final\mapstruct-processor-1.4.2.Final.jar;F:\Program Files\repository\org\apache\skywalking\apm-toolkit-log4j-2.x\8.1.0\apm-toolkit-log4j-2.x-8.1.0.jar;F:\Program Files\repository\org\apache\skywalking\apm-toolkit-trace\8.1.0\apm-toolkit-trace-8.1.0.jar;F:\Program Files\repository\com\tplink\nbu\skywalking-sdk\1.0.0\skywalking-sdk-1.0.0.jar;F:\Program Files\repository\io\grpc\grpc-netty-shaded\1.27.1\grpc-netty-shaded-1.27.1.jar;F:\Program Files\repository\io\grpc\grpc-core\1.27.1\grpc-core-1.27.1.jar;F:\Program Files\repository\io\grpc\grpc-api\1.27.1\grpc-api-1.27.1.jar;F:\Program Files\repository\io\grpc\grpc-context\1.27.1\grpc-context-1.27.1.jar;F:\Program Files\repository\org\codehaus\mojo\animal-sniffer-annotations\1.18\animal-sniffer-annotations-1.18.jar;F:\Program Files\repository\com\google\code\gson\gson\2.9.1\gson-2.9.1.jar;F:\Program Files\repository\com\google\android\annotations\4.1.1.4\annotations-4.1.1.4.jar;F:\Program Files\repository\io\perfmark\perfmark-api\0.19.0\perfmark-api-0.19.0.jar;F:\Program Files\repository\org\apache\httpcomponents\httpclient\4.5.14\httpclient-4.5.14.jar;F:\Program Files\repository\org\apache\httpcomponents\httpcore\4.4.16\httpcore-4.4.16.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter\2.7.8\spring-boot-starter-2.7.8.jar;F:\Program Files\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;F:\Program Files\repository\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-log4j2\2.7.8\spring-boot-starter-log4j2-2.7.8.jar;F:\Program Files\repository\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;F:\Program Files\repository\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;F:\Program Files\repository\org\apache\logging\log4j\log4j-slf4j-impl\2.17.2\log4j-slf4j-impl-2.17.2.jar;F:\Program Files\repository\org\apache\logging\log4j\log4j-core\2.17.2\log4j-core-2.17.2.jar;F:\Program Files\repository\org\apache\logging\log4j\log4j-jul\2.17.2\log4j-jul-2.17.2.jar;F:\Program Files\repository\org\projectlombok\lombok\1.18.24\lombok-1.18.24.jar;F:\Program Files\repository\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar;F:\Program Files\repository\com\tplink\cdd\vigi-common-eventbus\2.0.105-SNAPSHOT\vigi-common-eventbus-2.0.105-SNAPSHOT.jar;F:\Program Files\repository\com\tplink\smb\eventcenter.api\1.4.5\eventcenter.api-1.4.5.jar;F:\Program Files\repository\com\tplink\cdd\vigi-common-tpcloud\2.0.105-SNAPSHOT\vigi-common-tpcloud-2.0.105-SNAPSHOT.jar;F:\Program Files\repository\com\tplink\account-api-sdk\1.3.172\account-api-sdk-1.3.172.jar;F:\Program Files\repository\com\tplink\platform\common-grpc\1.0.4\common-grpc-1.0.4.jar;F:\Program Files\repository\com\google\protobuf\protobuf-java\3.19.2\protobuf-java-3.19.2.jar;F:\Program Files\repository\com\tplink\nbu\common\pii-mask-spring-boot-autoconfigure\2.1.51\pii-mask-spring-boot-autoconfigure-2.1.51.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-web\2.7.8\spring-boot-starter-web-2.7.8.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-json\2.7.8\spring-boot-starter-json-2.7.8.jar;F:\Program Files\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.4\jackson-datatype-jdk8-2.13.4.jar;F:\Program Files\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.4\jackson-module-parameter-names-2.13.4.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-tomcat\2.7.8\spring-boot-starter-tomcat-2.7.8.jar;F:\Program Files\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.71\tomcat-embed-websocket-9.0.71.jar;F:\Program Files\repository\org\springframework\spring-webmvc\5.3.25\spring-webmvc-5.3.25.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-validation\2.7.8\spring-boot-starter-validation-2.7.8.jar;F:\Program Files\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.71\tomcat-embed-el-9.0.71.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-starter-actuator\2.7.8\spring-boot-starter-actuator-2.7.8.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-actuator-autoconfigure\2.7.8\spring-boot-actuator-autoconfigure-2.7.8.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-actuator\2.7.8\spring-boot-actuator-2.7.8.jar;F:\Program Files\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.4\jackson-datatype-jsr310-2.13.4.jar;F:\Program Files\repository\com\hubspot\jackson\jackson-datatype-protobuf\0.9.15\jackson-datatype-protobuf-0.9.15.jar;F:\Program Files\repository\com\google\protobuf\protobuf-java-util\3.19.3\protobuf-java-util-3.19.3.jar;F:\Program Files\repository\com\google\code\findbugs\annotations\3.0.1\annotations-3.0.1.jar;F:\Program Files\repository\com\tplink\account-sdk\1.3.172\account-sdk-1.3.172.jar;F:\Program Files\repository\com\tplink\account\auth-sdk\1.1.621\auth-sdk-1.1.621.jar;F:\Program Files\repository\com\tplink\common\mail-sdk\1.1.507\mail-sdk-1.1.507.jar;F:\Program Files\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.71\tomcat-embed-core-9.0.71.jar;F:\Program Files\repository\org\apache\tomcat\tomcat-annotations-api\9.0.71\tomcat-annotations-api-9.0.71.jar;F:\Program Files\repository\com\tplink\cdd\common\components-email-cloud-platform\1.0.11\components-email-cloud-platform-1.0.11.jar;F:\Program Files\repository\com\tplink\cdd\common\components-email-api\1.0.11\components-email-api-1.0.11.jar;F:\Program Files\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;F:\Program Files\repository\com\tplink\cdd\common\components-email-common\1.0.11\components-email-common-1.0.11.jar;F:\Program Files\repository\com\tplink\smb\solution-components-lock-api\1.1.5\solution-components-lock-api-1.1.5.jar;F:\Program Files\repository\org\springframework\boot\spring-boot-autoconfigure\2.7.8\spring-boot-autoconfigure-2.7.8.jar;F:\Program Files\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;F:\Program Files\repository\com\tplink\smb\solution-components-cache-api\1.4.3\solution-components-cache-api-1.4.3.jar;F:\Program Files\repository\com\tplink\smb\solution-components-cache-mem\1.4.3\solution-components-cache-mem-1.4.3.jar;F:\Program Files\repository\com\github\ben-manes\caffeine\caffeine\2.9.3\caffeine-2.9.3.jar;F:\Program Files\repository\com\tplink\smb\solution-component-storage-api\1.4.10\solution-component-storage-api-1.4.10.jar;F:\Program Files\repository\org\apache\commons\commons-lang3\3.12.0\commons-lang3-3.12.0.jar;F:\Program Files\repository\com\tplink\smb\solution-component-storage-port-s3\1.4.10\solution-component-storage-port-s3-1.4.10.jar;F:\Program Files\repository\com\amazonaws\aws-java-sdk-s3\1.12.415\aws-java-sdk-s3-1.12.415.jar;F:\Program Files\repository\com\amazonaws\aws-java-sdk-kms\1.12.415\aws-java-sdk-kms-1.12.415.jar;F:\Program Files\repository\com\amazonaws\aws-java-sdk-core\1.12.415\aws-java-sdk-core-1.12.415.jar;F:\Program Files\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;F:\Program Files\repository\software\amazon\ion\ion-java\1.0.2\ion-java-1.0.2.jar;F:\Program Files\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-cbor\2.13.4\jackson-dataformat-cbor-2.13.4.jar;F:\Program Files\repository\joda-time\joda-time\2.8.1\joda-time-2.8.1.jar;F:\Program Files\repository\com\amazonaws\jmespath-java\1.12.415\jmespath-java-1.12.415.jar;F:\Program Files\repository\com\amazonaws\aws-java-sdk-sts\1.12.415\aws-java-sdk-sts-1.12.415.jar;F:\Program Files\repository\com\tplink\cdd\vigi-common-algorithm\2.0.105-SNAPSHOT\vigi-common-algorithm-2.0.105-SNAPSHOT.jar;F:\Program Files\repository\com\amazonaws\aws-java-sdk-lambda\1.11.923\aws-java-sdk-lambda-1.11.923.jar;F:\Program Files\repository\com\tplink\smb\eventcenter.kafka\1.4.5\eventcenter.kafka-1.4.5.jar;F:\Program Files\repository\com\tplink\smb\eventcenter.core\1.4.5\eventcenter.core-1.4.5.jar;F:\Program Files\repository\org\springframework\kafka\spring-kafka\2.8.11\spring-kafka-2.8.11.jar;F:\Program Files\repository\org\springframework\spring-messaging\5.3.25\spring-messaging-5.3.25.jar;F:\Program Files\repository\org\springframework\retry\spring-retry\1.3.4\spring-retry-1.3.4.jar;F:\Program Files\repository\org\apache\kafka\kafka-clients\3.1.2\kafka-clients-3.1.2.jar;F:\Program Files\repository\com\github\luben\zstd-jni\1.5.0-4\zstd-jni-1.5.0-4.jar;F:\Program Files\repository\org\lz4\lz4-java\1.8.0\lz4-java-1.8.0.jar;F:\Program Files\repository\org\xerial\snappy\snappy-java\1.1.8.4\snappy-java-1.1.8.4.jar;F:\Program Files\repository\io\micrometer\micrometer-core\1.9.7\micrometer-core-1.9.7.jar;F:\Program Files\repository\org\hdrhistogram\HdrHistogram\2.1.12\HdrHistogram-2.1.12.jar;F:\Program Files\repository\org\latencyutils\LatencyUtils\2.0.3\LatencyUtils-2.0.3.jar;F:\Program Files\repository\io\github\resilience4j\resilience4j-circuitbreaker\1.3.0\resilience4j-circuitbreaker-1.3.0.jar;F:\Program Files\repository\io\vavr\vavr\0.10.2\vavr-0.10.2.jar;F:\Program Files\repository\io\vavr\vavr-match\0.10.2\vavr-match-0.10.2.jar;F:\Program Files\repository\io\github\resilience4j\resilience4j-core\1.3.0\resilience4j-core-1.3.0.jar;F:\Program Files\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.4\jackson-annotations-2.13.4.jar;F:\Program Files\repository\com\fasterxml\jackson\core\jackson-core\2.13.4\jackson-core-2.13.4.jar;F:\Program Files\repository\com\esotericsoftware\kryo\5.5.0\kryo-5.5.0.jar;F:\Program Files\repository\com\esotericsoftware\reflectasm\1.11.9\reflectasm-1.11.9.jar;F:\Program Files\repository\com\esotericsoftware\minlog\1.3.1\minlog-1.3.1.jar;F:\Program Files\repository\com\tplink\smb\solution-components-lock-mem\1.3.4\solution-components-lock-mem-1.3.4.jar;F:\Program Files\repository\net\coobird\thumbnailator\0.4.20\thumbnailator-0.4.20.jar;F:\Program Files\repository\com\github\gotson\webp-imageio\0.2.2\webp-imageio-0.2.2.jar;F:\Program Files\repository\org\springframework\spring-test\5.2.12.RELEASE\spring-test-5.2.12.RELEASE.jar;F:\Program Files\repository\org\springframework\spring-core\5.3.25\spring-core-5.3.25.jar;F:\Program Files\repository\org\springframework\spring-jcl\5.3.25\spring-jcl-5.3.25.jar;F:\Program Files\repository\org\mockito\mockito-core\3.7.7\mockito-core-3.7.7.jar;F:\Program Files\repository\net\bytebuddy\byte-buddy\1.12.22\byte-buddy-1.12.22.jar;F:\Program Files\repository\net\bytebuddy\byte-buddy-agent\1.12.22\byte-buddy-agent-1.12.22.jar;F:\Program Files\repository\org\mockito\mockito-inline\3.7.7\mockito-inline-3.7.7.jar;F:\Program Files\repository\org\powermock\powermock-module-junit4\2.0.0\powermock-module-junit4-2.0.0.jar;F:\Program Files\repository\org\powermock\powermock-module-junit4-common\2.0.0\powermock-module-junit4-common-2.0.0.jar;F:\Program Files\repository\org\powermock\powermock-reflect\2.0.0\powermock-reflect-2.0.0.jar;F:\Program Files\repository\org\powermock\powermock-core\2.0.0\powermock-core-2.0.0.jar;F:\Program Files\repository\org\javassist\javassist\3.24.0-GA\javassist-3.24.0-GA.jar;F:\Program Files\repository\junit\junit\4.13.2\junit-4.13.2.jar;F:\Program Files\repository\org\hamcrest\hamcrest-core\2.2\hamcrest-core-2.2.jar;F:\Program Files\repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;F:\Program Files\repository\org\powermock\powermock-api-mockito2\2.0.0\powermock-api-mockito2-2.0.0.jar;F:\Program Files\repository\org\powermock\powermock-api-support\2.0.0\powermock-api-support-2.0.0.jar;F:\Program Files\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 @w@C:\Users\admin\AppData\Local\Temp\idea_working_dirs_junit.tmp @C:\Users\admin\AppData\Local\Temp\idea_junit.tmp Wanted but not invoked: personSyncEventPublisher.publishGroupDeleteSyncEvent( <any> ); -> at com.tplink.cdd.vms.person.core.port.eventcenter.PersonSyncEventPublisher.publishGroupDeleteSyncEvent(PersonSyncEventPublisher.java:55) However, there was exactly 1 interaction with this mock: personSyncEventPublisher.publishGroupUpdateSyncEvent( GroupUpdateSyncEventDTO(vmsId=vms-123, groupId=689d975cc473cf26b7fcd9b7, addedPersonIdList=[6879f25341daa77212c8a090], removedPersonIdList=[6879f25341daa77212c8a087, 6879f25341daa77212c8a089], notChangedPersonIdList=[6879f25341daa77212c8a088]) ); -> at com.tplink.cdd.vms.person.core.domain.group.UpdateGroupService.updateGroup(UpdateGroupService.java:93) Wanted but not invoked: personSyncEventPublisher.publishGroupDeleteSyncEvent( <any> ); -> at com.tplink.cdd.vms.person.core.port.eventcenter.PersonSyncEventPublisher.publishGroupDeleteSyncEvent(PersonSyncEventPublisher.java:55) However, there was exactly 1 interaction with this mock: personSyncEventPublisher.publishGroupUpdateSyncEvent( GroupUpdateSyncEventDTO(vmsId=vms-123, groupId=689d975cc473cf26b7fcd9b7, addedPersonIdList=[6879f25341daa77212c8a090], removedPersonIdList=[6879f25341daa77212c8a087, 6879f25341daa77212c8a089], notChangedPersonIdList=[6879f25341daa77212c8a088]) ); -> at com.tplink.cdd.vms.person.core.domain.group.UpdateGroupService.updateGroup(UpdateGroupService.java:93) at com.tplink.cdd.vms.person.core.port.eventcenter.PersonSyncEventPublisher.publishGroupDeleteSyncEvent(PersonSyncEventPublisher.java:55) at com.tplink.cdd.vms.person.core.domain.group.UpdateGroupServiceTest.testUpdateGroup_Success_WithPersonChanges(UpdateGroupServiceTest.java:249) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:54) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:99) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:105) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:40) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) 进程已结束,退出代码为 -1
08-15
内容概要:本文档主要展示了C语言中关于字符串处理、指针操作以及动态内存分配的相关代码示例。首先介绍了如何实现键值对(“key=value”)字符串的解析,包括去除多余空格和根据键获取对应值的功能,并提供了相应的测试用例。接着演示了从给定字符串中分离出奇偶位置字符的方法,并将结果分别存储到两个不同的缓冲区中。此外,还探讨了常量(const)修饰符在变量和指针中的应用规则,解释了不同类型指针的区别及其使用场景。最后,详细讲解了如何动态分配二维字符数组,并实现了对这类数组的排序与释放操作。 适合人群:具有C语言基础的程序员或计算机科学相关专业的学生,尤其是那些希望深入理解字符串处理、指针操作以及动态内存管理机制的学习者。 使用场景及目标:①掌握如何高效地解析键值对字符串并去除其中的空白字符;②学会编写能够正确处理奇偶索引字符的函数;③理解const修饰符的作用范围及其对程序逻辑的影响;④熟悉动态分配二维字符数组的技术,并能对其进行有效的排序和清理。 阅读建议:由于本资源涉及较多底层概念和技术细节,建议读者先复习C语言基础知识,特别是指针和内存管理部分。在学习过程中,可以尝试动手编写类似的代码片段,以便更好地理解和掌握文中所介绍的各种技巧。同时,注意观察代码注释,它们对于理解复杂逻辑非常有帮助。
当你在项目中同时引入了CameraX库,它自身可能依赖于某个版本的Guava(Google的通用集合库),而你又手动添加了一个不同的Guava版本(如`com.google.guava:guava:17.0`),这就会导致版本冲突。解决这种冲突通常需要采取以下步骤: 1. **查看冲突**: 首先,检查一下gradle构建脚本(`build.gradle`或`settings.gradle`)中的依赖声明,找出CameraX和Guava的具体依赖版本。 2. **排除特定依赖**: 如果发现是CameraX直接依赖的Guava版本与你的冲突,试着排除CameraX自带的Guava依赖,并明确指定你希望使用的Guava版本。在CameraX的`dependencies`块中添加类似这样的配置: ```groovy implementation 'androidx.camera:camera-core:1.x.y' { exclude group: 'com.google.guava', module: 'guava' } implementation 'com.google.guava:guava:x.y.z' ``` 3. **升级兼容版本**: 确保你的项目能接受CameraX的最低Guava版本需求。如果不行,尝试更新CameraX到支持你所选Guava版本的那个最新版。 4. **分模块管理**: 如果项目非常复杂,可以考虑将依赖冲突的部分放入单独的模块(module)中,这样每个模块有自己的依赖管理。 5. **错误处理**: 在代码中对可能出现的Guava类访问错误进行异常处理,以便程序在遇到冲突时仍然能运行,虽然这不是最佳实践。 在完成上述操作后,记得同步并构建你的项目看是否解决了冲突。如果还有问题,可以查阅官方文档、GitHub issue或者其他开发者论坛寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值