There is the following code:

short[][] test = new short[6][2]; Queue<short[]> arr = new LinkedList<short[]>(); 

The test array is populated as follows:

 [[1,2],[3,4],[1,2],[3,4],[1,2],[3,4]] 

There is a function to add an item to LinkedList :

 private static void AddElement(short[] in, Queue<short[]> link_arr, int max_size) { // удалить самый старый элемент если очередь больше max_size if (link_arr.size() > max_size) { link_arr.poll(); } link_arr.add(in); Set<short[]> set_arr = new LinkedHashSet<short[]>(link_arr); link_arr.clear(); link_arr.addAll(set_arr); } 

Called as follows:

 for (int i = 0; i < test.length; i++) { AddElement(test[i], arr, max_size); } 

As a result, after the execution of the program in arr still duplicate elements. If arr is just a list of short , then everything works.

Can Java libraries get a unique list, or will I have to write everything myself?

  • HashMap watched? Or HashSet - JVic
  • If we are talking about HashMap or HashSet instead of LinkedList, then no, I just need the functionality of the queue. If instead of LinkedHashSet, then tried, the same. - user239737

2 answers 2

Using an array as a key in a Map bad idea, because you cannot count on the fact that two arrays containing the same elements will have the same hash code and return true when comparing with equals .

One solution to the problem is to create a wrapper class for the array that implements the hashCode and equals methods:

 private static class Element { public final short[] values; public Element(short[] values) { this.values = values; } @Override public boolean equals(Object obj) { if (obj instanceof Element) { return Arrays.equals(values, ((Element)obj).values); } return false; } @Override public int hashCode() { return Arrays.hashCode(values); } } public static void main(String[] args) { short[][] test = { { 1,2 }, { 3,4 }, { 1,2 }, { 3,4 }, { 1,2 }, { 3,4 } }; Set<Element> uniqueElements = new HashSet<>(); for (short[] group : test) { uniqueElements.add(new Element(group)); } List<short[]> result = new ArrayList<>(); for (Element element : uniqueElements) { result.add(element.values); } } 

Instead of HashSet you can use LinkedHashSet , as well as LinkedList instead of ArrayList , to get unique elements is not important.

In Java 8, the main method might look like this:

 short[][] test = { { 1,2 }, { 3,4 }, { 1,2 }, { 3,4 }, { 1,2 }, { 3,4 } }; List<short[]> result = Stream.of(test) .map(Element::new) .distinct() .map(e -> e.values) .collect(Collectors.toList()); 

If you need to add items to the queue one by one in a separate method, you can convert the source code like this:

 public static void main(String[] args) { short[][] test = { { 1,2 }, { 3,4 }, { 1,2 }, { 3, 4 }, { 5,6 }, { 3,4 } }; Queue<Element> queue = new LinkedList<>(); for (short[] group : test) { addElement(group, queue, 10); } } private static void addElement(short[] array, Queue<Element> queue, int maxSize) { Element element = new Element(array); if (queue.contains(element)) { return; } while (queue.size() >= maxSize) { queue.poll(); } queue.add(element); } 

There is, instead of blocking the addition of a duplicate, you need to add an element to the end of the queue, then instead

 if (queue.contains(element)) { return; } 

enough to use

 queue.remove(element); 
  • @ user239737 what exactly is not clear? The Arrays.equals method compares two arrays elementwise. If they differ, the method returns true . - Regent
  • Everything, ok, blunted a little while I wrote. Thank. - user239737

Since different objects of arrays are added, without equals() redefined, set compares hash codes (references) to the parent Object , and they differ from different objects. If you want to delete semantically different values ​​at the logic level of the application, then the condition for comparing objects must prescribe itself (override equals() )

  • As I understand it, I need to override equals () and hashCode () and after that only unique values ​​will appear on LinkedHashSet? - user239737
  • Yes. By the way, judging by the code, the choice of LinkedHashSet not conditional, it provides the order of the components in the order of addition, which is unnecessary. - Tachkin
  • LinkedHashSet in this example may not be entirely due, but the order of adding is critical to me, since need exactly the queue. - user239737
  • Another question if you can? I add items to the queue implemented by a static method in the class (I created a service class with a set of static methods to use throughout the project). If I redefine equals () in order for AddElement to work correctly, but in the future I will need another equals (), then how can I get around this situation? - user239737
  • To be honest, I consider the declaration of static methods and variables the collapse of OOP design (I got infected from reading Fowler). The best option to determine the behavior of the object in the object itself. <br/> If we consider just such an arrangement, which is, then it is better to rewrite the static class as the variable logic to the host comparator and make comparisons in the same class, but with different comparators. - Tachkin