I am having trouble using my custom set,MySet, using the basic function of union and intersecting. The program compiles without error but just returns an empty set.
Anybody see where the problem is?
public class MySet<E> extends TreeSet<E> {
Set<E> set;
public MySet(){
set = null;
}
public MySet(Set<E> set){
this.set = set;
}
public void union(Set<E> s){
set.addAll(s);
}
public void intersection(Set<E> s){
set.retainAll(s);
}
}
Main method
public class TestSet {
public static void main(String[] args) throws FileNotFoundException{
File f1 = new File("courseList1.txt");
File f2 = new File("courseList2.txt");
Scanner scan1 = new Scanner(f1);
Scanner scan2 = new Scanner(f2);
Set<Coarse> set1 = new HashSet<Coarse>();
Set<Coarse> set2 = new HashSet<Coarse>();
MySet<Coarse> mySet = new MySet<Coarse>(set1);
String designator;
int number;
while(scan1.hasNext()){
designator = scan1.next();
number = scan1.nextInt();
set1.add(new Coarse(designator, number));
}
while(scan2.hasNext()){
designator = scan2.next();
number = scan2.nextInt();
set2.add(new Coarse(designator, number));
}
mySet.union(set2);
mySet.intersection(set2);
}
}
It seems that you are trying to implement composition and at the same time extending the tree set, but that is not a good practice, you either use composition and implement the Set interface (backend with a TreeSet) or extends the tree set
Extending the TreeSet
class MySet<E> extends TreeSet<E> {
public void union(Set<E> s){
addAll(s);
}
public void intersection(Set<E> s){
retainAll(s);
}
}
using composition
class MySet<E> implements Set<E> {
private TreeSet<E> set;
public MySet(TreeSet<E> set) {
this.set = new TreeSet<>(set);
}
public void union(Set<E> s){
set.addAll(s);
}
public void intersection(Set<E> s){
set.retainAll(s);
}
#Override
public int size() {
return set.size();
}
#Override
public boolean isEmpty() {
return set.isEmpty();
}
#Override
public boolean contains(Object o) {
return set.contains(o);
}
#Override
public Iterator<E> iterator() {
return set.iterator();
}
#Override
public Object[] toArray() {
return set.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return set.toArray(a);
}
#Override
public boolean add(E e) {
return set.add(e);
}
#Override
public boolean remove(Object o) {
return set.remove(o);
}
#Override
public boolean containsAll(Collection<?> c) {
return set.containsAll(c);
}
#Override
public boolean addAll(Collection<? extends E> c) {
return set.addAll(c);
}
#Override
public boolean retainAll(Collection<?> c) {
return set.retainAll(c);
}
#Override
public boolean removeAll(Collection<?> c) {
return set.removeAll(c);
}
#Override
public void clear() {
set.clear();
}
#Override
public boolean equals(Object o) {
return set.equals(o);
}
#Override
public int hashCode() {
return set.hashCode();
}
}
Related
Let's say I have a department class that contains a list of employees, as follows:
public class Departement {
List<Employees> employeesList;
public List<Employees> getEmployeesList() {
return employeesList;
}
public Departement setEmployeesList(List<Employees> employeesList) {
this.employeesList = employeesList;
return this;
}
}
There is a case where I need all employees on a separate list. To do that I'm using streams, as follows:
List<Departement> departments ...
List<Employees> employees = departments.stream().flatMap(departement ->
departement.getEmployeesList().stream()).collect(Collectors.toList()));
In case I delete a department in the department list, is there a way to automatically delete its employees in the employees list made by stream.flatMap?
There is no direct way to automatically delete the objects from the employee list. You can use one of the below options:
Option 1:
First, delete all the employees of the to-be-deleted department and delete the department from the department list.
employees.removeAll(departement2.getEmployeesList());
departments.remove(departement2);
Option 2:
Delete the department from the department list and then recreate the employee list:
departments.remove(departement2);
employees = departments.stream().flatMap(departement ->departement.getEmployeesList().stream()).collect(Collectors.toList());
Just to try it I implemented a generic Type of a List backed by a parent List:
public class FlatMapList<C,P> implements List<C>
{
private Function<P,List<C>> getter;
private List<P> parents;
public FlatMapList(List<P> parents, Function<P,List<C>> getter)
{
this.parents = parents;
this.getter = getter;
}
#Override
public int size()
{
return getList().size();
}
#Override
public boolean isEmpty()
{
return getList().isEmpty();
}
#Override
public boolean contains(Object o)
{
return getList().contains(o);
}
#Override
public Iterator<C> iterator()
{
return getList().iterator();
}
#Override
public Object[] toArray()
{
return getList().toArray();
}
#Override
public <T> T[] toArray(T[] a)
{
return getList().toArray(a);
}
#Override
public boolean add(C e)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean containsAll(Collection<?> c)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean addAll(Collection<? extends C> c)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean addAll(int index, Collection<? extends C> c)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean removeAll(Collection<?> c)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public boolean retainAll(Collection<?> c)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public void clear()
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public C get(int index)
{
return getList().get(index);
}
#Override
public C set(int index, C element)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public void add(int index, C element)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public C remove(int index)
{
throw new UnsupportedOperationException("List is readonly");
}
#Override
public int indexOf(Object o)
{
return getList().indexOf(o);
}
#Override
public int lastIndexOf(Object o)
{
return getList().lastIndexOf(o);
}
#Override
public ListIterator<C> listIterator()
{
return getList().listIterator();
}
#Override
public ListIterator<C> listIterator(int index)
{
return getList().listIterator(index);
}
#Override
public List<C> subList(int fromIndex, int toIndex)
{
return getList().subList(fromIndex,toIndex);
}
#Override
public String toString( ) {
return getList().toString();
}
private List<C> getList() {
return Collections.unmodifiableList(parents.stream().flatMap(p ->
this.getter.apply(p).stream()).collect(Collectors.toList()));
}
public static void main(String[] args) {
Department dep1 = new Department();
dep1.setName("D1");
dep1.setEmployeesList(Arrays.asList(new Employee("e1"),new Employee("e2")));
Department dep2 = new Department();
dep2.setName("D2");
dep2.setEmployeesList(Arrays.asList(new Employee("e3"),new Employee("e4")));
List<Department> deps = new ArrayList<>(Arrays.asList(dep1,dep2));
// Create a List backed with the parent list and the getter for the children
List<Employee> employees = new FlatMapList<>(deps,Department::getEmployeesList);
System.out.println(employees);
deps.remove(dep1);
System.out.println(employees);
}
}
Output
[Employee [name=e1], Employee [name=e2], Employee [name=e3], Employee [name=e4]]
[Employee [name=e3], Employee [name=e4]]
I have two entities: Deck and Card
#Entity
class Deck {
private String name;
#ManyToMany
private List<Card> cards;
}
#Entity
class Card {
private String name;
#ManyToMany
private List<Deck> decks;
}
And I have a Model for each entity
class DeckModel {
private String name;
private List<CardModel> cards;
}
class CardModel {
private String name;
private List<DeckModel> decks;
}
Now I want to convert a Deck in a DeckModel so I created this two functions:
DeckModel convert(Deck deck) {
DeckModel model = new DeckModel();
model.setName(deck.getName());
model.setCards(deck.getCards().stream()
.map(card -> convert(card))
.collect(Collectors.toList()));
return model;
}
CardModel convert(Card card) {
CardModel model = new CardModel();
model.setName(card.getName());
model.setDecks(deck.getDecks().stream()
.map(deck -> convert(deck))
.collect(Collectors.toList()));
return model;
}
The problem with this piece of code is that when i convert Card(s) in CardModel(s) I trigger the lazy load of all cards related to the deck I'm converting but what I want is to decide later on in my application if I want or not to fetch all the Card(s) related to the Deck.
Is there an easy/standar way to do this?
You need to iterate in for loop and set it manually as the models in list differ.
You cannot use Reflection as the models field differ.
else you could use BeanUtils.copyProperties() to map fields of DeckEntity into Deck
and set that Deck object in your list.
You can verify in advance if a lazy hibernate collection is initialized through the method:
Hibernate.isInitialized
example:
CardModel convert(Card card) {
CardModel model = new CardModel();
if (Hibernate.isInitialized(deck.getDecks())) {
model.setName(card.getName());
model.setDecks(deck.getDecks().stream()
.map(deck -> convert(deck))
.collect(Collectors.toList()));
}
return model;
}
By using it you can verify its state and if not initialized just return empty list.
This is the solution I implemented for my own problem, maybe it can be useful to someone else.
I have created a LazyList object which require a ListInitializer, on the first operation the LazyList will call ListInitializer which will return a List, the LazyList will then delegate all operations to the List returned from the ListInitializer. In my specific case the ListInitializer will convert and return the converted List. So doing my List will not be converted if the LazyList will never be used.
public class LazyList<T> implements List<T> {
private final ListInitializerSingleton<T> singleton;
public LazyList(ListInitializer<T> initializer) {
this.singleton = new ListInitializerSingleton<>(initializer);
}
#Override
public int size() {
return singleton.list().size();
}
#Override
public boolean isEmpty() {
return singleton.list().isEmpty();
}
#Override
public boolean contains(Object o) {
return singleton.list().contains(o);
}
#NotNull
#Override
public Iterator<T> iterator() {
return singleton.list().iterator();
}
#NotNull
#Override
public Object[] toArray() {
return singleton.list().toArray();
}
#NotNull
#Override
public <T1> T1[] toArray(#NotNull T1[] a) {
return singleton.list().toArray(a);
}
#Override
public boolean add(T t) {
return singleton.list().add(t);
}
#Override
public boolean remove(Object o) {
return singleton.list().remove(o);
}
#Override
public boolean containsAll(#NotNull Collection<?> c) {
return singleton.list().containsAll(c);
}
#Override
public boolean addAll(#NotNull Collection<? extends T> c) {
return singleton.list().addAll(c);
}
#Override
public boolean addAll(int index, #NotNull Collection<? extends T> c) {
return singleton.list().addAll(index, c);
}
#Override
public boolean removeAll(#NotNull Collection<?> c) {
return singleton.list().removeAll(c);
}
#Override
public boolean retainAll(#NotNull Collection<?> c) {
return singleton.list().retainAll(c);
}
#Override
public void clear() {
singleton.list().clear();
}
#Override
public T get(int index) {
return singleton.list().get(index);
}
#Override
public T set(int index, T element) {
return singleton.list().set(index, element);
}
#Override
public void add(int index, T element) {
singleton.list().add(index, element);
}
#Override
public T remove(int index) {
return singleton.list().remove(index);
}
#Override
public int indexOf(Object o) {
return singleton.list().indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
return singleton.list().lastIndexOf(o);
}
#NotNull
#Override
public ListIterator<T> listIterator() {
return singleton.list().listIterator();
}
#NotNull
#Override
public ListIterator<T> listIterator(int index) {
return singleton.list().listIterator(index);
}
#NotNull
#Override
public List<T> subList(int fromIndex, int toIndex) {
return singleton.list().subList(fromIndex, toIndex);
}
#FunctionalInterface
public interface ListInitializer<T> {
List<T> initialize();
}
private class ListInitializerSingleton<T> {
private final ListInitializer<T> initializer;
private List<T> list;
ListInitializerSingleton(ListInitializer<T> initializer) {
this.initializer = initializer;
}
List<T> list() {
if (list == null) {
list = initializer.initialize();
}
return list;
}
}
}
Usage:
DeckModel convert(Deck deck) {
DeckModel model = new DeckModel();
model.setName(deck.getName());
LazyList<CardModel> cards = new LazyList<>(() -> {
deck.getCards().stream()
.map(card -> convert(card))
.collect(Collectors.toList());
})
model.setCards(cards);
return model;
}
CardModel convert(Card card) {
CardModel model = new CardModel();
model.setName(card.getName());
LazyList<DeckModel> decks = new LazyList<>(() -> {
card.getDecks().stream()
.map(deck -> convert(deck))
.collect(Collectors.toList());
})
model.setDecks(deks);
return model;
}
If you look at the this vey simple code snipped, is there a valid way to actually call baz?
public class Foo {
static class Bar<T> {
public void baz(Class<? extends List<T>> cls) {
}
}
public static void main(String[] args) {
Bar<String> bar = new Bar<>();
// does not compile
bar.baz(ArrayList<String>.class);
bar.baz((Class<List<String>>) ArrayList.class);
bar.baz(new ArrayList<String>().getClass());
}
}
I can think of two ways (they both have their disadvantages):
1.
Bar bar = new Bar<>();
bar.baz(ArrayList.class);
This of course removes the String type parameter, which you might not want.
2.
Bar<String> bar = new Bar<>();
bar.baz(MyClass.class);
Here, MyClass is declared like a wrapper of ArrayList<String>:
class MyClass implements List<String> {
private ArrayList<String> inner = new ArrayList<>();
#Override
public int size() {
return inner.size();
}
#Override
public boolean isEmpty() {
return inner.isEmpty();
}
#Override
public boolean contains(Object o) {
return inner.contains(o);
}
#Override
public Iterator<String> iterator() {
return inner.iterator();
}
#Override
public Object[] toArray() {
return inner.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return inner.toArray(a);
}
#Override
public boolean add(String s) {
return inner.add(s);
}
#Override
public boolean remove(Object o) {
return inner.remove(o);
}
#Override
public boolean containsAll(Collection<?> c) {
return inner.containsAll(c);
}
#Override
public boolean addAll(Collection<? extends String> c) {
return inner.addAll(c);
}
#Override
public boolean addAll(int index, Collection<? extends String> c) {
return inner.addAll(index, c);
}
#Override
public boolean removeAll(Collection<?> c) {
return inner.removeAll(c);
}
#Override
public boolean retainAll(Collection<?> c) {
return inner.retainAll(c);
}
#Override
public void clear() {
inner.clear();
}
#Override
public String get(int index) {
return inner.get(index);
}
#Override
public String set(int index, String element) {
return inner.set(index, element);
}
#Override
public void add(int index, String element) {
inner.add(index, element);
}
#Override
public String remove(int index) {
return inner.remove(index);
}
#Override
public int indexOf(Object o) {
return inner.indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
return inner.lastIndexOf(o);
}
#Override
public ListIterator<String> listIterator() {
return inner.listIterator();
}
#Override
public ListIterator<String> listIterator(int index) {
return inner.listIterator(index);
}
#Override
public List<String> subList(int fromIndex, int toIndex) {
return inner.subList(fromIndex, toIndex);
}
}
The disadvantage of this is of course, wasting time to create a brand new class that implements List<String>. If you are lazy, you can try extending AbstractList<String> instead.
There is any way i can do next with out getting the yellow warning / #SuppressWarnings("unchecked")
Generics objects :
P=product to compare,C = custoumer
public static myComparator<Product<P>> comparator= new myComparator<Product<P>>();
comparator declaration is outside "insertIntoMap" method,
i cant use the Product object inside "insertIntoMap" method .
public static <P,C> TreeMap<P, C> insertIntoMap(LinkedHashSet<P> set,C[] ac){
#SuppressWarnings("unchecked")
TreeMap<P,C> treeMap = new TreeMap<P,C>((Comparator<? super P>) comparator);
int itrIndex=0;
Iterator<P> itr = set.iterator();
while(itr.hasNext()){
treeMap.put(itr.next(), ac[itrIndex]);
itrIndex++;
}
return (TreeMap<P, C>) treeMap;
}
public static class myComparator<E> implements Comparator<Product<? super E>>{
#Override
public int compare(Product<? super E> o1, Product<? super E> o2) {
if(o1.getName().length()>o2.getName().length())
return 1;
else return -1;
}
}
Product Class :
public static class Product<E> implements Comparable<E>{
private E serialNum;
private String name;
Product(E serialNum,String name){
setSerialNum(serialNum);
setName(name);
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result;
result = prime * result + ((serialNum == null) ? 0 : serialNum.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
Product<?> other = (Product<?>) obj;
if (serialNum.equals(other.serialNum))return true;
else return false;
}
public E getSerialNum() {
return serialNum;
}
public void setSerialNum(E serialNum) {
this.serialNum = serialNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return serialNum.toString()+": "+name;
}
#Override
public int compareTo(E o) {
if(this.hashCode()>o.hashCode())return 1;
else if(this.hashCode()<o.hashCode()) return -1;
else return -1;
}
}
Thanks !
From the code you posted it seems:
myComparator should not be generic:
public class myComperator implements Comparator<Product<?>> {
#Override
public int compare(Product<?> o1, Product<?> o2) {
if (o1.getName().length() > o2.getName().length())
return 1;
else if (o1.getName().length() < o2.getName().length())
return -1;
else
return -1;
}
}
insertIntoMap should only work for P extending Product. Otherwise you cannot use myComperator (which compares Products):
public static <P extends Product<?>, C> TreeMap<P, C> insertIntoMap(
LinkedHashSet<P> set, C[] ac) {
TreeMap<P, C> treeMap = new TreeMap<P, C>(new myComperator());
int itrIndex = 0;
Iterator<P> itr = set.iterator();
while (itr.hasNext()) {
treeMap.put(itr.next(), ac[itrIndex]);
itrIndex++;
}
return treeMap;
}
I have a class that extends DataRow:
import org.jdesktop.dataset.DataRow;
public class MainDataRow extends DataRow {
private MainDataTable baseDataTable;
protected MainDataRow(MainDataTable dt) {
super(dt);
this.baseDataTable = dt;
}
public int getId() { return (int) super.getValue(baseDataTable.getColId()); };
public void setId(int id) { super.setValue(baseDataTable.getColId(), id); };
public int getDelta() { return (int) super.getValue(baseDataTable.getColDelta()); };
public void setDelta(int delta) { super.setValue(baseDataTable.getColDelta(), delta); };
public String getNombre() { return (String) super.getValue(baseDataTable.getColNombre()); };
public void setNombre(String nombre) { super.setValue(baseDataTable.getColNombre(), nombre); };
Also MainDataTable extends DataTable, and returns valid columns for getColId(), getColDelta(), getColNombre().
I would like to do:
MainDataTable dt = new MainDataTable(ds);
MainDataRow dr = (MainDataRow) dt.appendRow();
But this is not possible due to a CastClassException (dt.appendRow return DataRow and MainDataRow is extending DataRow, not vice versa, so the only possibility could be something similar to DataRow dr = (DataRow) new MainDataRow(dt);).
In c++ it can be easyly achieved through DataRowBuilder, overriding NewRowFromBuilder() in MainDataTable and overriding the protected creator from DataRowBuilder in MainDataRow (Casting DataRow to Strongly-Typed DataRow: How do they do it?).
How could I do it in Java?
Edit
MainDataTable class:
public class MainDataTable extends TypedDataTable<MainDataRow> {
...
}
And TypedDataTable class:
public abstract class TypedDataTable<TypeOfRow> extends DataTable {
protected boolean locked;
public TypedDataTable(DataSet ds, boolean appendRowSupported) {
super(ds);
InitClass();
super.setAppendRowSupported(appendRowSupported);
locked = false;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public abstract DataRow appendRow();
#Override
public abstract DataRow appendRowNoEvent();
public abstract void InitVars();
public abstract void InitClass();
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}
Override appendRow() and appendRowNoEvent() in MainDataTable to return a MainDataRow
public abstract class TypedDataTable<TypeOfRow extends DataRow> extends DataTable {
protected boolean locked;
public TypedDataTable(DataSet ds, boolean appendRowSupported) {
super(ds);
InitClass();
super.setAppendRowSupported(appendRowSupported);
locked = false;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public TypeOfRow appendRowNoEvent() {
if (appendRowSupported) {
TypeOfRow row = createDataRow(); //<-- HERE we create a MainDataRow!!!
rows.add(row);
return row;
} else {
return null;
}
}
#Override
public TypeOfRow appendRow() {
return (TypeOfRow)super.appendRow();
}
public abstract TypeOfRow createDataRow();
public abstract void InitVars();
public abstract void InitClass();
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}